diff options
Diffstat (limited to 'dbm/src')
-rw-r--r-- | dbm/src/.cvsignore | 1 | ||||
-rw-r--r-- | dbm/src/Makefile.in | 69 | ||||
-rw-r--r-- | dbm/src/Makefile.win | 96 | ||||
-rw-r--r-- | dbm/src/db.c | 144 | ||||
-rw-r--r-- | dbm/src/h_bigkey.c | 677 | ||||
-rw-r--r-- | dbm/src/h_func.c | 211 | ||||
-rw-r--r-- | dbm/src/h_log2.c | 56 | ||||
-rw-r--r-- | dbm/src/h_page.c | 1288 | ||||
-rw-r--r-- | dbm/src/hash.c | 1258 | ||||
-rw-r--r-- | dbm/src/hash_buf.c | 408 | ||||
-rw-r--r-- | dbm/src/hsearch.c | 108 | ||||
-rw-r--r-- | dbm/src/memmove.c | 150 | ||||
-rw-r--r-- | dbm/src/mktemp.c | 168 | ||||
-rw-r--r-- | dbm/src/ndbm.c | 195 | ||||
-rw-r--r-- | dbm/src/nsres.c | 311 | ||||
-rw-r--r-- | dbm/src/snprintf.c | 75 | ||||
-rw-r--r-- | dbm/src/strerror.c | 78 |
17 files changed, 0 insertions, 5293 deletions
diff --git a/dbm/src/.cvsignore b/dbm/src/.cvsignore deleted file mode 100644 index f3c7a7c5d..000000000 --- a/dbm/src/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -Makefile diff --git a/dbm/src/Makefile.in b/dbm/src/Makefile.in deleted file mode 100644 index 216faa439..000000000 --- a/dbm/src/Makefile.in +++ /dev/null @@ -1,69 +0,0 @@ -# -# The contents of this file are subject to the Netscape Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/NPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# - -DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -LIBRARY_NAME = mozdbm_s -LIB_IS_C_ONLY = 1 - -CSRCS = \ - db.c \ - h_bigkey.c \ - h_func.c \ - h_log2.c \ - h_page.c \ - hash.c \ - hash_buf.c \ - hsearch.c \ - mktemp.c \ - ndbm.c \ - strerror.c \ - nsres.c \ - $(NULL) - -ifeq (,$(filter -DHAVE_MEMMOVE=1,$(DEFS))) -CSRC += memmove.c -endif - -ifeq (,$(filter -DHAVE_SNPRINTF=1,$(DEFS))) -CSRC += snprintf.c -endif - -LOCAL_INCLUDES = -I$(srcdir)/../include - -FORCE_STATIC_LIB = 1 - -include $(topsrcdir)/config/rules.mk - -DEFINES += -DMEMMOVE -D__DBINTERFACE_PRIVATE $(SECURITY_FLAG) -ifeq ($(OS_ARCH), Linux) -DEFINES += -D_BSD_SOURCE -endif - -ifeq ($(OS_ARCH),AIX) -OS_LIBS += -lc_r -endif - diff --git a/dbm/src/Makefile.win b/dbm/src/Makefile.win deleted file mode 100644 index 1d49e5f91..000000000 --- a/dbm/src/Makefile.win +++ /dev/null @@ -1,96 +0,0 @@ -# The contents of this file are subject to the Netscape Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/NPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): - - -#//------------------------------------------------------------------------ -#// -#// Makefile to build the cert library -#// -#//------------------------------------------------------------------------ - -!if "$(MOZ_BITS)" == "16" -!ifndef MOZ_DEBUG -OPTIMIZER=-Os -UDEBUG -DNDEBUG -!endif -!endif - -#//------------------------------------------------------------------------ -#// -#// Specify the depth of the current directory relative to the -#// root of NS -#// -#//------------------------------------------------------------------------ -DEPTH= ..\.. - -!ifndef MAKE_OBJ_TYPE -MAKE_OBJ_TYPE=EXE -!endif - -#//------------------------------------------------------------------------ -#// -#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...) -#// -#//------------------------------------------------------------------------ -LIBNAME=dbm$(MOZ_BITS) -PDBFILE=$(LIBNAME).pdb - -#//------------------------------------------------------------------------ -#// -#// Define the files necessary to build the target (ie. OBJS) -#// -#//------------------------------------------------------------------------ -OBJS= \ - .\$(OBJDIR)\db.obj \ - .\$(OBJDIR)\h_bigkey.obj \ - .\$(OBJDIR)\h_func.obj \ - .\$(OBJDIR)\h_log2.obj \ - .\$(OBJDIR)\h_page.obj \ - .\$(OBJDIR)\hash.obj \ - .\$(OBJDIR)\hash_buf.obj \ - .\$(OBJDIR)\hsearch.obj \ - .\$(OBJDIR)\memmove.obj \ - .\$(OBJDIR)\mktemp.obj \ - .\$(OBJDIR)\ndbm.obj \ - .\$(OBJDIR)\snprintf.obj \ - .\$(OBJDIR)\strerror.obj \ - .\$(OBJDIR)\nsres.obj \ - $(NULL) - -#//------------------------------------------------------------------------ -#// -#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...) -#// (these must be defined before the common makefiles are included) -#// -#//------------------------------------------------------------------------ -LIBRARY = .\$(OBJDIR)\$(LIBNAME).lib -LINCS = -I..\include - -#//------------------------------------------------------------------------ -#// -#// Include the common makefile rules -#// -#//------------------------------------------------------------------------ -include <$(DEPTH)/config/rules.mak> - -CFLAGS = $(CFLAGS) -DMOZILLA_CLIENT - -install:: $(LIBRARY) - $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib - - diff --git a/dbm/src/db.c b/dbm/src/db.c deleted file mode 100644 index e4b1fff8f..000000000 --- a/dbm/src/db.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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[] = "@(#)db.c 8.4 (Berkeley) 2/21/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#ifndef __DBINTERFACE_PRIVATE -#define __DBINTERFACE_PRIVATE -#endif -#ifdef macintosh -#include <unix.h> -#else -#include <sys/types.h> -#endif - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <stdio.h> - -#include "mcom_db.h" - -/* a global flag that locks closed all databases */ -int all_databases_locked_closed = 0; - -/* set or unset a global lock flag to disable the - * opening of any DBM file - */ -void -dbSetOrClearDBLock(DBLockFlagEnum type) -{ - if(type == LockOutDatabase) - all_databases_locked_closed = 1; - else - all_databases_locked_closed = 0; -} - -#if defined(__WATCOMC__) || defined(__WATCOM_CPLUSPLUS__) -DB * -#else -PR_IMPLEMENT(DB *) -#endif -dbopen(const char *fname, int flags,int mode, DBTYPE type, const void *openinfo) -{ - - /* lock out all file databases. Let in-memory databases through - */ - if(all_databases_locked_closed && fname) - { - errno = EINVAL; - return(NULL); - } - -#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN) - - -#if 0 /* most systems dont have EXLOCK and SHLOCK */ -#define USE_OPEN_FLAGS \ - (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \ - O_RDWR | O_SHLOCK | O_TRUNC) -#else -#define USE_OPEN_FLAGS \ - (O_CREAT | O_EXCL | O_RDONLY | \ - O_RDWR | O_TRUNC) -#endif - - if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0) - switch (type) { -/* we don't need btree and recno right now */ -#if 0 - case DB_BTREE: - return (__bt_open(fname, flags & USE_OPEN_FLAGS, - mode, openinfo, flags & DB_FLAGS)); - case DB_RECNO: - return (__rec_open(fname, flags & USE_OPEN_FLAGS, - mode, openinfo, flags & DB_FLAGS)); -#endif - - case DB_HASH: - return (__hash_open(fname, flags & USE_OPEN_FLAGS, - mode, (const HASHINFO *)openinfo, flags & DB_FLAGS)); - default: - break; - } - errno = EINVAL; - return (NULL); -} - -static int -__dberr() -{ - return (RET_ERROR); -} - -/* - * __DBPANIC -- Stop. - * - * Parameters: - * dbp: pointer to the DB structure. - */ -void -__dbpanic(DB *dbp) -{ - /* The only thing that can succeed is a close. */ - dbp->del = (int (*)(const struct __db *, const DBT *, uint))__dberr; - dbp->fd = (int (*)(const struct __db *))__dberr; - dbp->get = (int (*)(const struct __db *, const DBT *, DBT *, uint))__dberr; - dbp->put = (int (*)(const struct __db *, DBT *, const DBT *, uint))__dberr; - dbp->seq = (int (*)(const struct __db *, DBT *, DBT *, uint))__dberr; - dbp->sync = (int (*)(const struct __db *, uint))__dberr; -} diff --git a/dbm/src/h_bigkey.c b/dbm/src/h_bigkey.c deleted file mode 100644 index fe5d8f800..000000000 --- a/dbm/src/h_bigkey.c +++ /dev/null @@ -1,677 +0,0 @@ -/*- - * 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 - * Margo Seltzer. - * - * 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[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -/* - * PACKAGE: hash - * DESCRIPTION: - * Big key/data handling for the hashing package. - * - * ROUTINES: - * External - * __big_keydata - * __big_split - * __big_insert - * __big_return - * __big_delete - * __find_last_page - * Internal - * collect_key - * collect_data - */ - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP) -#include <sys/param.h> -#endif - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef DEBUG -#include <assert.h> -#endif - -#include "mcom_db.h" -#include "hash.h" -#include "page.h" -/* #include "extern.h" */ - -static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int)); -static int collect_data __P((HTAB *, BUFHEAD *, int, int)); - -/* - * Big_insert - * - * You need to do an insert and the key/data pair is too big - * - * Returns: - * 0 ==> OK - *-1 ==> ERROR - */ -extern int -__big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) -{ - register uint16 *p; - uint key_size, n, val_size; - uint16 space, move_bytes, off; - char *cp, *key_data, *val_data; - - cp = bufp->page; /* Character pointer of p. */ - p = (uint16 *)cp; - - key_data = (char *)key->data; - key_size = key->size; - val_data = (char *)val->data; - val_size = val->size; - - /* First move the Key */ - for (space = FREESPACE(p) - BIGOVERHEAD; key_size; - space = FREESPACE(p) - BIGOVERHEAD) { - move_bytes = PR_MIN(space, key_size); - off = OFFSET(p) - move_bytes; - memmove(cp + off, key_data, move_bytes); - key_size -= move_bytes; - key_data += move_bytes; - n = p[0]; - p[++n] = off; - p[0] = ++n; - FREESPACE(p) = off - PAGE_META(n); - OFFSET(p) = off; - p[n] = PARTIAL_KEY; - bufp = __add_ovflpage(hashp, bufp); - if (!bufp) - return (-1); - n = p[0]; - if (!key_size) { - if (FREESPACE(p)) { - move_bytes = PR_MIN(FREESPACE(p), val_size); - off = OFFSET(p) - move_bytes; - p[n] = off; - memmove(cp + off, val_data, move_bytes); - val_data += move_bytes; - val_size -= move_bytes; - p[n - 2] = FULL_KEY_DATA; - FREESPACE(p) = FREESPACE(p) - move_bytes; - OFFSET(p) = off; - } else - p[n - 2] = FULL_KEY; - } - p = (uint16 *)bufp->page; - cp = bufp->page; - bufp->flags |= BUF_MOD; - } - - /* Now move the data */ - for (space = FREESPACE(p) - BIGOVERHEAD; val_size; - space = FREESPACE(p) - BIGOVERHEAD) { - move_bytes = PR_MIN(space, val_size); - /* - * Here's the hack to make sure that if the data ends on the - * same page as the key ends, FREESPACE is at least one. - */ - if (space == val_size && val_size == val->size) - move_bytes--; - off = OFFSET(p) - move_bytes; - memmove(cp + off, val_data, move_bytes); - val_size -= move_bytes; - val_data += move_bytes; - n = p[0]; - p[++n] = off; - p[0] = ++n; - FREESPACE(p) = off - PAGE_META(n); - OFFSET(p) = off; - if (val_size) { - p[n] = FULL_KEY; - bufp = __add_ovflpage(hashp, bufp); - if (!bufp) - return (-1); - cp = bufp->page; - p = (uint16 *)cp; - } else - p[n] = FULL_KEY_DATA; - bufp->flags |= BUF_MOD; - } - return (0); -} - -/* - * Called when bufp's page contains a partial key (index should be 1) - * - * All pages in the big key/data pair except bufp are freed. We cannot - * free bufp because the page pointing to it is lost and we can't get rid - * of its pointer. - * - * Returns: - * 0 => OK - *-1 => ERROR - */ -extern int -__big_delete(HTAB *hashp, BUFHEAD *bufp) -{ - register BUFHEAD *last_bfp, *rbufp; - uint16 *bp, pageno; - int key_done, n; - - rbufp = bufp; - last_bfp = NULL; - bp = (uint16 *)bufp->page; - pageno = 0; - key_done = 0; - - while (!key_done || (bp[2] != FULL_KEY_DATA)) { - if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) - key_done = 1; - - /* - * If there is freespace left on a FULL_KEY_DATA page, then - * the data is short and fits entirely on this page, and this - * is the last page. - */ - if (bp[2] == FULL_KEY_DATA && FREESPACE(bp)) - break; - pageno = bp[bp[0] - 1]; - rbufp->flags |= BUF_MOD; - rbufp = __get_buf(hashp, pageno, rbufp, 0); - if (last_bfp) - __free_ovflpage(hashp, last_bfp); - last_bfp = rbufp; - if (!rbufp) - return (-1); /* Error. */ - bp = (uint16 *)rbufp->page; - } - - /* - * If we get here then rbufp points to the last page of the big - * key/data pair. Bufp points to the first one -- it should now be - * empty pointing to the next page after this pair. Can't free it - * because we don't have the page pointing to it. - */ - - /* This is information from the last page of the pair. */ - n = bp[0]; - pageno = bp[n - 1]; - - /* Now, bp is the first page of the pair. */ - bp = (uint16 *)bufp->page; - if (n > 2) { - /* There is an overflow page. */ - bp[1] = pageno; - bp[2] = OVFLPAGE; - bufp->ovfl = rbufp->ovfl; - } else - /* This is the last page. */ - bufp->ovfl = NULL; - n -= 2; - bp[0] = n; - FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); - OFFSET(bp) = hashp->BSIZE - 1; - - bufp->flags |= BUF_MOD; - if (rbufp) - __free_ovflpage(hashp, rbufp); - if (last_bfp != rbufp) - __free_ovflpage(hashp, last_bfp); - - hashp->NKEYS--; - return (0); -} -/* - * Returns: - * 0 = key not found - * -1 = get next overflow page - * -2 means key not found and this is big key/data - * -3 error - */ -extern int -__find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size) -{ - register uint16 *bp; - register char *p; - int ksize; - uint16 bytes; - char *kkey; - - bp = (uint16 *)bufp->page; - p = bufp->page; - ksize = size; - kkey = key; - - for (bytes = hashp->BSIZE - bp[ndx]; - bytes <= size && bp[ndx + 1] == PARTIAL_KEY; - bytes = hashp->BSIZE - bp[ndx]) { - if (memcmp(p + bp[ndx], kkey, bytes)) - return (-2); - kkey += bytes; - ksize -= bytes; - bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0); - if (!bufp) - return (-3); - p = bufp->page; - bp = (uint16 *)p; - ndx = 1; - } - - if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) { -#ifdef HASH_STATISTICS - ++hash_collisions; -#endif - return (-2); - } else - return (ndx); -} - -/* - * Given the buffer pointer of the first overflow page of a big pair, - * find the end of the big pair - * - * This will set bpp to the buffer header of the last page of the big pair. - * It will return the pageno of the overflow page following the last page - * of the pair; 0 if there isn't any (i.e. big pair is the last key in the - * bucket) - */ -extern uint16 -__find_last_page(HTAB *hashp, BUFHEAD **bpp) -{ - BUFHEAD *bufp; - uint16 *bp, pageno; - uint n; - - bufp = *bpp; - bp = (uint16 *)bufp->page; - for (;;) { - n = bp[0]; - - /* - * This is the last page if: the tag is FULL_KEY_DATA and - * either only 2 entries OVFLPAGE marker is explicit there - * is freespace on the page. - */ - if (bp[2] == FULL_KEY_DATA && - ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp)))) - break; - - /* LJM bound the size of n to reasonable limits - */ - if(n > hashp->BSIZE/sizeof(uint16)) - return(0); - - pageno = bp[n - 1]; - bufp = __get_buf(hashp, pageno, bufp, 0); - if (!bufp) - return (0); /* Need to indicate an error! */ - bp = (uint16 *)bufp->page; - } - - *bpp = bufp; - if (bp[0] > 2) - return (bp[3]); - else - return (0); -} - -/* - * Return the data for the key/data pair that begins on this page at this - * index (index should always be 1). - */ -extern int -__big_return( - HTAB *hashp, - BUFHEAD *bufp, - int ndx, - DBT *val, - int set_current) -{ - BUFHEAD *save_p; - uint16 *bp, len, off, save_addr; - char *tp; - - bp = (uint16 *)bufp->page; - while (bp[ndx + 1] == PARTIAL_KEY) { - bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!bufp) - return (-1); - bp = (uint16 *)bufp->page; - ndx = 1; - } - - if (bp[ndx + 1] == FULL_KEY) { - bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!bufp) - return (-1); - bp = (uint16 *)bufp->page; - save_p = bufp; - save_addr = save_p->addr; - off = bp[1]; - len = 0; - } else - if (!FREESPACE(bp)) { - /* - * This is a hack. We can't distinguish between - * FULL_KEY_DATA that contains complete data or - * incomplete data, so we require that if the data - * is complete, there is at least 1 byte of free - * space left. - */ - off = bp[bp[0]]; - len = bp[1] - off; - save_p = bufp; - save_addr = bufp->addr; - bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!bufp) - return (-1); - bp = (uint16 *)bufp->page; - } else { - /* The data is all on one page. */ - tp = (char *)bp; - off = bp[bp[0]]; - val->data = (uint8 *)tp + off; - val->size = bp[1] - off; - if (set_current) { - if (bp[0] == 2) { /* No more buckets in - * chain */ - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else { - hashp->cpage = __get_buf(hashp, - bp[bp[0] - 1], bufp, 0); - if (!hashp->cpage) - return (-1); - hashp->cndx = 1; - if (!((uint16 *) - hashp->cpage->page)[0]) { - hashp->cbucket++; - hashp->cpage = NULL; - } - } - } - return (0); - } - - val->size = collect_data(hashp, bufp, (int)len, set_current); - if ((val->size + 1) == 0) /* unsigned ints are not really negative */ - return (-1); - if (save_p->addr != save_addr) { - /* We are pretty short on buffers. */ - errno = EINVAL; /* OUT OF BUFFERS */ - return (-1); - } - memmove(hashp->tmp_buf, (save_p->page) + off, len); - val->data = (uint8 *)hashp->tmp_buf; - return (0); -} -/* - * Count how big the total datasize is by recursing through the pages. Then - * allocate a buffer and copy the data as you recurse up. - */ -static int -collect_data( - HTAB *hashp, - BUFHEAD *bufp, - int len, int set) -{ - register uint16 *bp; - register char *p; - BUFHEAD *xbp; - uint16 save_addr; - int mylen, totlen; - - p = bufp->page; - bp = (uint16 *)p; - mylen = hashp->BSIZE - bp[1]; - - /* if mylen ever goes negative it means that the - * page is screwed up. - */ - if(mylen < 0) - return (-1); - - save_addr = bufp->addr; - - if (bp[2] == FULL_KEY_DATA) { /* End of Data */ - totlen = len + mylen; - if (hashp->tmp_buf) - free(hashp->tmp_buf); - if ((hashp->tmp_buf = (char *)malloc((size_t)totlen)) == NULL) - return (-1); - if (set) { - hashp->cndx = 1; - if (bp[0] == 2) { /* No more buckets in chain */ - hashp->cpage = NULL; - hashp->cbucket++; - } else { - hashp->cpage = - __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!hashp->cpage) - return (-1); - else if (!((uint16 *)hashp->cpage->page)[0]) { - hashp->cbucket++; - hashp->cpage = NULL; - } - } - } - } else { - xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!xbp || ((totlen = - collect_data(hashp, xbp, len + mylen, set)) < 1)) - return (-1); - } - if (bufp->addr != save_addr) { - errno = EINVAL; /* Out of buffers. */ - return (-1); - } - memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], (size_t)mylen); - return (totlen); -} - -/* - * Fill in the key and data for this big pair. - */ -extern int -__big_keydata( - HTAB *hashp, - BUFHEAD *bufp, - DBT *key, DBT *val, - int set) -{ - key->size = collect_key(hashp, bufp, 0, val, set); - if ((key->size + 1) == 0) /* same compile warning about comparing signed and unsigned */ - return (-1); - key->data = (uint8 *)hashp->tmp_key; - return (0); -} - -/* - * Count how big the total key size is by recursing through the pages. Then - * collect the data, allocate a buffer and copy the key as you recurse up. - */ -static int -collect_key( - HTAB *hashp, - BUFHEAD *bufp, - int len, - DBT *val, - int set) -{ - BUFHEAD *xbp; - char *p; - int mylen, totlen; - uint16 *bp, save_addr; - - p = bufp->page; - bp = (uint16 *)p; - mylen = hashp->BSIZE - bp[1]; - - save_addr = bufp->addr; - totlen = len + mylen; - if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */ - if (hashp->tmp_key != NULL) - free(hashp->tmp_key); - if ((hashp->tmp_key = (char *)malloc((size_t)totlen)) == NULL) - return (-1); - if (__big_return(hashp, bufp, 1, val, set)) - return (-1); - } else { - xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!xbp || ((totlen = - collect_key(hashp, xbp, totlen, val, set)) < 1)) - return (-1); - } - if (bufp->addr != save_addr) { - errno = EINVAL; /* MIS -- OUT OF BUFFERS */ - return (-1); - } - memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], (size_t)mylen); - return (totlen); -} - -/* - * Returns: - * 0 => OK - * -1 => error - */ -extern int -__big_split( - HTAB *hashp, - BUFHEAD *op, /* Pointer to where to put keys that go in old bucket */ - BUFHEAD *np, /* Pointer to new bucket page */ - /* Pointer to first page containing the big key/data */ - BUFHEAD *big_keyp, - uint32 addr, /* Address of big_keyp */ - uint32 obucket,/* Old Bucket */ - SPLIT_RETURN *ret) -{ - register BUFHEAD *tmpp; - register uint16 *tp; - BUFHEAD *bp; - DBT key, val; - uint32 change; - uint16 free_space, n, off; - - bp = big_keyp; - - /* Now figure out where the big key/data goes */ - if (__big_keydata(hashp, big_keyp, &key, &val, 0)) - return (-1); - change = (__call_hash(hashp,(char*) key.data, key.size) != obucket); - - if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) { - if (!(ret->nextp = - __get_buf(hashp, ret->next_addr, big_keyp, 0))) - return (-1);; - } else - ret->nextp = NULL; - - /* Now make one of np/op point to the big key/data pair */ -#ifdef DEBUG - assert(np->ovfl == NULL); -#endif - if (change) - tmpp = np; - else - tmpp = op; - - tmpp->flags |= BUF_MOD; -#ifdef DEBUG1 - (void)fprintf(stderr, - "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr, - (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); -#endif - tmpp->ovfl = bp; /* one of op/np point to big_keyp */ - tp = (uint16 *)tmpp->page; - - -#if 0 /* this get's tripped on database corrupted error */ - assert(FREESPACE(tp) >= OVFLSIZE); -#endif - if(FREESPACE(tp) < OVFLSIZE) - return(DATABASE_CORRUPTED_ERROR); - - n = tp[0]; - off = OFFSET(tp); - free_space = FREESPACE(tp); - tp[++n] = (uint16)addr; - tp[++n] = OVFLPAGE; - tp[0] = n; - OFFSET(tp) = off; - FREESPACE(tp) = free_space - OVFLSIZE; - - /* - * Finally, set the new and old return values. BIG_KEYP contains a - * pointer to the last page of the big key_data pair. Make sure that - * big_keyp has no following page (2 elements) or create an empty - * following page. - */ - - ret->newp = np; - ret->oldp = op; - - tp = (uint16 *)big_keyp->page; - big_keyp->flags |= BUF_MOD; - if (tp[0] > 2) { - /* - * There may be either one or two offsets on this page. If - * there is one, then the overflow page is linked on normally - * and tp[4] is OVFLPAGE. If there are two, tp[4] contains - * the second offset and needs to get stuffed in after the - * next overflow page is added. - */ - n = tp[4]; - free_space = FREESPACE(tp); - off = OFFSET(tp); - tp[0] -= 2; - FREESPACE(tp) = free_space + OVFLSIZE; - OFFSET(tp) = off; - tmpp = __add_ovflpage(hashp, big_keyp); - if (!tmpp) - return (-1); - tp[4] = n; - } else - tmpp = big_keyp; - - if (change) - ret->newp = tmpp; - else - ret->oldp = tmpp; - return (0); -} diff --git a/dbm/src/h_func.c b/dbm/src/h_func.c deleted file mode 100644 index 5819efe23..000000000 --- a/dbm/src/h_func.c +++ /dev/null @@ -1,211 +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 - * Margo Seltzer. - * - * 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[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#ifndef macintosh -#include <sys/types.h> -#endif -#include "mcom_db.h" -#include "hash.h" -#include "page.h" -/* #include "extern.h" */ - -#if 0 -static uint32 hash1 __P((const void *, size_t)); -static uint32 hash2 __P((const void *, size_t)); -static uint32 hash3 __P((const void *, size_t)); -#endif -static uint32 hash4 __P((const void *, size_t)); - -/* Global default hash function */ -uint32 (*__default_hash) __P((const void *, size_t)) = hash4; - -/* - * HASH FUNCTIONS - * - * Assume that we've already split the bucket to which this key hashes, - * calculate that bucket, and check that in fact we did already split it. - * - * This came from ejb's hsearch. - */ - -#define PRIME1 37 -#define PRIME2 1048583 - -#if 0 -static uint32 -hash1(const void *keyarg, register size_t len) -{ - register const uint8 *key; - register uint32 h; - - /* Convert string to integer */ - for (key = (const uint8 *)keyarg, h = 0; len--;) - h = h * PRIME1 ^ (*key++ - ' '); - h %= PRIME2; - return (h); -} - -/* - * Phong's linear congruential hash - */ -#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) - -static uint32 -hash2(const void *keyarg, size_t len) -{ - register const uint8 *e, *key; - register uint32 h; - register uint8 c; - - key = (const uint8 *)keyarg; - e = key + len; - for (h = 0; key != e;) { - c = *key++; - if (!c && key > e) - break; - dcharhash(h, c); - } - return (h); -} - -/* - * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the "leftover bytes" - * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If - * this routine is heavily used enough, it's worth the ugly coding. - * - * OZ's original sdbm hash - */ -static uint32 -hash3(const void *keyarg, register size_t len) -{ - register const uint8 *key; - register size_t loop; - register uint32 h; - -#define HASHC h = *key++ + 65599 * h - - h = 0; - key = (const uint8 *)keyarg; - if (len > 0) { - loop = (len + 8 - 1) >> 3; - - switch (len & (8 - 1)) { - case 0: - do { - HASHC; - /* FALLTHROUGH */ - case 7: - HASHC; - /* FALLTHROUGH */ - case 6: - HASHC; - /* FALLTHROUGH */ - case 5: - HASHC; - /* FALLTHROUGH */ - case 4: - HASHC; - /* FALLTHROUGH */ - case 3: - HASHC; - /* FALLTHROUGH */ - case 2: - HASHC; - /* FALLTHROUGH */ - case 1: - HASHC; - } while (--loop); - } - } - return (h); -} -#endif /* 0 */ - -/* Hash function from Chris Torek. */ -static uint32 -hash4(const void *keyarg, register size_t len) -{ - register const uint8 *key; - register size_t loop; - register uint32 h; - -#define HASH4a h = (h << 5) - h + *key++; -#define HASH4b h = (h << 5) + h + *key++; -#define HASH4 HASH4b - - h = 0; - key = (const uint8 *)keyarg; - if (len > 0) { - loop = (len + 8 - 1) >> 3; - - switch (len & (8 - 1)) { - case 0: - do { - HASH4; - /* FALLTHROUGH */ - case 7: - HASH4; - /* FALLTHROUGH */ - case 6: - HASH4; - /* FALLTHROUGH */ - case 5: - HASH4; - /* FALLTHROUGH */ - case 4: - HASH4; - /* FALLTHROUGH */ - case 3: - HASH4; - /* FALLTHROUGH */ - case 2: - HASH4; - /* FALLTHROUGH */ - case 1: - HASH4; - } while (--loop); - } - } - return (h); -} diff --git a/dbm/src/h_log2.c b/dbm/src/h_log2.c deleted file mode 100644 index 4d8b0a715..000000000 --- a/dbm/src/h_log2.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * 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 - * Margo Seltzer. - * - * 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[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#include <stdio.h> -#ifndef macintosh -#include <sys/types.h> -#endif -#include "mcom_db.h" - -uint32 __log2(uint32 num) -{ - register uint32 i, limit; - - limit = 1; - for (i = 0; limit < num; limit = limit << 1, i++) {} - return (i); -} diff --git a/dbm/src/h_page.c b/dbm/src/h_page.c deleted file mode 100644 index 2c4b50f87..000000000 --- a/dbm/src/h_page.c +++ /dev/null @@ -1,1288 +0,0 @@ -/*- - * 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 - * Margo Seltzer. - * - * 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(unix) -#define MY_LSEEK lseek -#else -#define MY_LSEEK new_lseek -extern long new_lseek(int fd, long pos, int start); -#endif - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -/* - * PACKAGE: hashing - * - * DESCRIPTION: - * Page manipulation for hashing package. - * - * ROUTINES: - * - * External - * __get_page - * __add_ovflpage - * Internal - * overflow_page - * open_temp - */ -#ifndef macintosh -#include <sys/types.h> -#endif - -#if defined(macintosh) -#include <unistd.h> -#endif - -#include <errno.h> -#include <fcntl.h> -#if defined(_WIN32) || defined(_WINDOWS) -#include <io.h> -#endif -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP) -#include <unistd.h> -#endif - -#include <assert.h> - -#include "mcom_db.h" -#include "hash.h" -#include "page.h" -/* #include "extern.h" */ - -extern int mkstempflags(char *path, int extraFlags); - -static uint32 *fetch_bitmap __P((HTAB *, uint32)); -static uint32 first_free __P((uint32)); -static int open_temp __P((HTAB *)); -static uint16 overflow_page __P((HTAB *)); -static void squeeze_key __P((uint16 *, const DBT *, const DBT *)); -static int ugly_split - __P((HTAB *, uint32, BUFHEAD *, BUFHEAD *, int, int)); - -#define PAGE_INIT(P) { \ - ((uint16 *)(P))[0] = 0; \ - ((uint16 *)(P))[1] = hashp->BSIZE - 3 * sizeof(uint16); \ - ((uint16 *)(P))[2] = hashp->BSIZE; \ -} - -/* implement a new lseek using lseek that - * writes zero's when extending a file - * beyond the end. - */ -long new_lseek(int fd, long offset, int origin) -{ - long cur_pos=0; - long end_pos=0; - long seek_pos=0; - - if(origin == SEEK_CUR) - { - if(offset < 1) - return(lseek(fd, offset, SEEK_CUR)); - - cur_pos = lseek(fd, 0, SEEK_CUR); - - if(cur_pos < 0) - return(cur_pos); - } - - end_pos = lseek(fd, 0, SEEK_END); - if(end_pos < 0) - return(end_pos); - - if(origin == SEEK_SET) - seek_pos = offset; - else if(origin == SEEK_CUR) - seek_pos = cur_pos + offset; - else if(origin == SEEK_END) - seek_pos = end_pos + offset; - else - { - assert(0); - return(-1); - } - - /* the seek position desired is before the - * end of the file. We don't need - * to do anything special except the seek. - */ - if(seek_pos <= end_pos) - return(lseek(fd, seek_pos, SEEK_SET)); - - /* the seek position is beyond the end of the - * file. Write zero's to the end. - * - * we are already at the end of the file so - * we just need to "write()" zeros for the - * difference between seek_pos-end_pos and - * then seek to the position to finish - * the call - */ - { - char buffer[1024]; - long len = seek_pos-end_pos; - memset(&buffer, 0, 1024); - while(len > 0) - { - write(fd, (char*)&buffer, (size_t)(1024 > len ? len : 1024)); - len -= 1024; - } - return(lseek(fd, seek_pos, SEEK_SET)); - } - -} - -/* - * This is called AFTER we have verified that there is room on the page for - * the pair (PAIRFITS has returned true) so we go right ahead and start moving - * stuff on. - */ -static void -putpair(char *p, const DBT *key, DBT * val) -{ - register uint16 *bp, n, off; - - bp = (uint16 *)p; - - /* Enter the key first. */ - n = bp[0]; - - off = OFFSET(bp) - key->size; - memmove(p + off, key->data, key->size); - bp[++n] = off; - - /* Now the data. */ - off -= val->size; - memmove(p + off, val->data, val->size); - bp[++n] = off; - - /* Adjust page info. */ - bp[0] = n; - bp[n + 1] = off - ((n + 3) * sizeof(uint16)); - bp[n + 2] = off; -} - -/* - * Returns: - * 0 OK - * -1 error - */ -extern int -__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx) -{ - register uint16 *bp, newoff; - register int n; - uint16 pairlen; - - bp = (uint16 *)bufp->page; - n = bp[0]; - - if (bp[ndx + 1] < REAL_KEY) - return (__big_delete(hashp, bufp)); - if (ndx != 1) - newoff = bp[ndx - 1]; - else - newoff = hashp->BSIZE; - pairlen = newoff - bp[ndx + 1]; - - if (ndx != (n - 1)) { - /* Hard Case -- need to shuffle keys */ - register int i; - register char *src = bufp->page + (int)OFFSET(bp); - uint32 dst_offset = (uint32)OFFSET(bp) + (uint32)pairlen; - register char *dst = bufp->page + dst_offset; - uint32 length = bp[ndx + 1] - OFFSET(bp); - - /* - * +-----------+XXX+---------+XXX+---------+---------> +infinity - * | | | | - * 0 src_offset dst_offset BSIZE - * - * Dst_offset is > src_offset, so if src_offset were bad, dst_offset - * would be too, therefore we check only dst_offset. - * - * If dst_offset is >= BSIZE, either OFFSET(bp), or pairlen, or both - * is corrupted. - * - * Once we know dst_offset is < BSIZE, we can subtract it from BSIZE - * to get an upper bound on length. - */ - if(dst_offset > (uint32)hashp->BSIZE) - return(DATABASE_CORRUPTED_ERROR); - - if(length > (uint32)(hashp->BSIZE - dst_offset)) - return(DATABASE_CORRUPTED_ERROR); - - memmove(dst, src, length); - - /* Now adjust the pointers */ - for (i = ndx + 2; i <= n; i += 2) { - if (bp[i + 1] == OVFLPAGE) { - bp[i - 2] = bp[i]; - bp[i - 1] = bp[i + 1]; - } else { - bp[i - 2] = bp[i] + pairlen; - bp[i - 1] = bp[i + 1] + pairlen; - } - } - } - /* Finally adjust the page data */ - bp[n] = OFFSET(bp) + pairlen; - bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(uint16); - bp[0] = n - 2; - hashp->NKEYS--; - - bufp->flags |= BUF_MOD; - return (0); -} -/* - * Returns: - * 0 ==> OK - * -1 ==> Error - */ -extern int -__split_page(HTAB *hashp, uint32 obucket, uint32 nbucket) -{ - register BUFHEAD *new_bufp, *old_bufp; - register uint16 *ino; - register uint16 *tmp_uint16_array; - register char *np; - DBT key, val; - uint16 n, ndx; - int retval; - uint16 copyto, diff, moved; - size_t off; - char *op; - - copyto = (uint16)hashp->BSIZE; - off = (uint16)hashp->BSIZE; - old_bufp = __get_buf(hashp, obucket, NULL, 0); - if (old_bufp == NULL) - return (-1); - new_bufp = __get_buf(hashp, nbucket, NULL, 0); - if (new_bufp == NULL) - return (-1); - - old_bufp->flags |= (BUF_MOD | BUF_PIN); - new_bufp->flags |= (BUF_MOD | BUF_PIN); - - ino = (uint16 *)(op = old_bufp->page); - np = new_bufp->page; - - moved = 0; - - for (n = 1, ndx = 1; n < ino[0]; n += 2) { - if (ino[n + 1] < REAL_KEY) { - retval = ugly_split(hashp, obucket, old_bufp, new_bufp, - (int)copyto, (int)moved); - old_bufp->flags &= ~BUF_PIN; - new_bufp->flags &= ~BUF_PIN; - return (retval); - - } - key.data = (uint8 *)op + ino[n]; - - /* check here for ino[n] being greater than - * off. If it is then the database has - * been corrupted. - */ - if(ino[n] > off) - return(DATABASE_CORRUPTED_ERROR); - - key.size = off - ino[n]; - -#ifdef DEBUG - /* make sure the size is positive */ - assert(((int)key.size) > -1); -#endif - - if (__call_hash(hashp, (char *)key.data, key.size) == obucket) { - /* Don't switch page */ - diff = copyto - off; - if (diff) { - copyto = ino[n + 1] + diff; - memmove(op + copyto, op + ino[n + 1], - off - ino[n + 1]); - ino[ndx] = copyto + ino[n] - ino[n + 1]; - ino[ndx + 1] = copyto; - } else - copyto = ino[n + 1]; - ndx += 2; - } else { - /* Switch page */ - val.data = (uint8 *)op + ino[n + 1]; - val.size = ino[n] - ino[n + 1]; - - /* if the pair doesn't fit something is horribly - * wrong. LJM - */ - tmp_uint16_array = (uint16*)np; - if(!PAIRFITS(tmp_uint16_array, &key, &val)) - return(DATABASE_CORRUPTED_ERROR); - - putpair(np, &key, &val); - moved += 2; - } - - off = ino[n + 1]; - } - - /* Now clean up the page */ - ino[0] -= moved; - FREESPACE(ino) = copyto - sizeof(uint16) * (ino[0] + 3); - OFFSET(ino) = copyto; - -#ifdef DEBUG3 - (void)fprintf(stderr, "split %d/%d\n", - ((uint16 *)np)[0] / 2, - ((uint16 *)op)[0] / 2); -#endif - /* unpin both pages */ - old_bufp->flags &= ~BUF_PIN; - new_bufp->flags &= ~BUF_PIN; - return (0); -} - -/* - * Called when we encounter an overflow or big key/data page during split - * handling. This is special cased since we have to begin checking whether - * the key/data pairs fit on their respective pages and because we may need - * overflow pages for both the old and new pages. - * - * The first page might be a page with regular key/data pairs in which case - * we have a regular overflow condition and just need to go on to the next - * page or it might be a big key/data pair in which case we need to fix the - * big key/data pair. - * - * Returns: - * 0 ==> success - * -1 ==> failure - */ - -/* the maximum number of loops we will allow UGLY split to chew - * on before we assume the database is corrupted and throw it - * away. - */ -#define MAX_UGLY_SPLIT_LOOPS 10000 - -static int -ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp, - BUFHEAD *new_bufp,/* Same as __split_page. */ int copyto, int moved) - /* 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 uint16 *ino; /* Page keys come off of */ - register uint16 *np; /* New page */ - register uint16 *op; /* Page keys go on to if they aren't moving */ - uint32 loop_detection=0; - - BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ - DBT key, val; - SPLIT_RETURN ret; - uint16 n, off, ov_addr, scopyto; - char *cino; /* Character value of ino */ - int status; - - bufp = old_bufp; - ino = (uint16 *)old_bufp->page; - np = (uint16 *)new_bufp->page; - op = (uint16 *)old_bufp->page; - last_bfp = NULL; - scopyto = (uint16)copyto; /* ANSI */ - - n = ino[0] - 1; - while (n < ino[0]) { - - - /* this function goes nuts sometimes and never returns. - * I havent found the problem yet but I need a solution - * so if we loop too often we assume a database curruption error - * :LJM - */ - loop_detection++; - - if(loop_detection > MAX_UGLY_SPLIT_LOOPS) - return DATABASE_CORRUPTED_ERROR; - - if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) { - if ((status = __big_split(hashp, old_bufp, - new_bufp, bufp, bufp->addr, obucket, &ret))) - return (status); - old_bufp = ret.oldp; - if (!old_bufp) - return (-1); - op = (uint16 *)old_bufp->page; - new_bufp = ret.newp; - if (!new_bufp) - return (-1); - np = (uint16 *)new_bufp->page; - bufp = ret.nextp; - if (!bufp) - return (0); - cino = (char *)bufp->page; - ino = (uint16 *)cino; - last_bfp = ret.nextp; - } else if (ino[n + 1] == OVFLPAGE) { - ov_addr = ino[n]; - /* - * Fix up the old page -- the extra 2 are the fields - * which contained the overflow information. - */ - ino[0] -= (moved + 2); - FREESPACE(ino) = - scopyto - sizeof(uint16) * (ino[0] + 3); - OFFSET(ino) = scopyto; - - bufp = __get_buf(hashp, ov_addr, bufp, 0); - if (!bufp) - return (-1); - - ino = (uint16 *)bufp->page; - n = 1; - scopyto = hashp->BSIZE; - moved = 0; - - if (last_bfp) - __free_ovflpage(hashp, last_bfp); - last_bfp = bufp; - } - /* Move regular sized pairs of there are any */ - off = hashp->BSIZE; - for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) { - cino = (char *)ino; - key.data = (uint8 *)cino + ino[n]; - key.size = off - ino[n]; - val.data = (uint8 *)cino + ino[n + 1]; - val.size = ino[n] - ino[n + 1]; - off = ino[n + 1]; - - if (__call_hash(hashp, (char*)key.data, key.size) == obucket) { - /* Keep on old page */ - if (PAIRFITS(op, (&key), (&val))) - putpair((char *)op, &key, &val); - else { - old_bufp = - __add_ovflpage(hashp, old_bufp); - if (!old_bufp) - return (-1); - op = (uint16 *)old_bufp->page; - putpair((char *)op, &key, &val); - } - old_bufp->flags |= BUF_MOD; - } else { - /* Move to new page */ - if (PAIRFITS(np, (&key), (&val))) - putpair((char *)np, &key, &val); - else { - new_bufp = - __add_ovflpage(hashp, new_bufp); - if (!new_bufp) - return (-1); - np = (uint16 *)new_bufp->page; - putpair((char *)np, &key, &val); - } - new_bufp->flags |= BUF_MOD; - } - } - } - if (last_bfp) - __free_ovflpage(hashp, last_bfp); - return (0); -} - -/* - * Add the given pair to the page - * - * Returns: - * 0 ==> OK - * 1 ==> failure - */ -extern int -__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT * val) -{ - register uint16 *bp, *sop; - int do_expand; - - bp = (uint16 *)bufp->page; - do_expand = 0; - while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) - /* Exception case */ - if (bp[2] == FULL_KEY_DATA && bp[0] == 2) - /* This is the last page of a big key/data pair - and we need to add another page */ - break; - else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { - bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!bufp) - { -#ifdef DEBUG - assert(0); -#endif - return (-1); - } - bp = (uint16 *)bufp->page; - } else - /* Try to squeeze key on this page */ - if (FREESPACE(bp) > PAIRSIZE(key, val)) { - { - squeeze_key(bp, key, val); - - /* LJM: I added this because I think it was - * left out on accident. - * if this isn't incremented nkeys will not - * be the actual number of keys in the db. - */ - hashp->NKEYS++; - return (0); - } - } else { - bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); - if (!bufp) - { -#ifdef DEBUG - assert(0); -#endif - return (-1); - } - bp = (uint16 *)bufp->page; - } - - if (PAIRFITS(bp, key, val)) - putpair(bufp->page, key, (DBT *)val); - else { - do_expand = 1; - bufp = __add_ovflpage(hashp, bufp); - if (!bufp) - { -#ifdef DEBUG - assert(0); -#endif - return (-1); - } - sop = (uint16 *)bufp->page; - - if (PAIRFITS(sop, key, val)) - putpair((char *)sop, key, (DBT *)val); - else - if (__big_insert(hashp, bufp, key, val)) - { -#ifdef DEBUG - assert(0); -#endif - return (-1); - } - } - bufp->flags |= BUF_MOD; - /* - * If the average number of keys per bucket exceeds the fill factor, - * expand the table. - */ - hashp->NKEYS++; - if (do_expand || - (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR)) - return (__expand_table(hashp)); - return (0); -} - -/* - * - * Returns: - * pointer on success - * NULL on error - */ -extern BUFHEAD * -__add_ovflpage(HTAB *hashp, BUFHEAD *bufp) -{ - register uint16 *sp; - uint16 ndx, ovfl_num; -#ifdef DEBUG1 - int tmp1, tmp2; -#endif - sp = (uint16 *)bufp->page; - - /* Check if we are dynamically determining the fill factor */ - if (hashp->FFACTOR == DEF_FFACTOR) { - hashp->FFACTOR = sp[0] >> 1; - if (hashp->FFACTOR < MIN_FFACTOR) - hashp->FFACTOR = MIN_FFACTOR; - } - bufp->flags |= BUF_MOD; - ovfl_num = overflow_page(hashp); -#ifdef DEBUG1 - tmp1 = bufp->addr; - tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0; -#endif - if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1))) - return (NULL); - bufp->ovfl->flags |= BUF_MOD; -#ifdef DEBUG1 - (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n", - tmp1, tmp2, bufp->ovfl->addr); -#endif - ndx = sp[0]; - /* - * Since a pair is allocated on a page only if there's room to add - * an overflow page, we know that the OVFL information will fit on - * the page. - */ - sp[ndx + 4] = OFFSET(sp); - sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE; - sp[ndx + 1] = ovfl_num; - sp[ndx + 2] = OVFLPAGE; - sp[0] = ndx + 2; -#ifdef HASH_STATISTICS - hash_overflows++; -#endif - return (bufp->ovfl); -} - -/* - * Returns: - * 0 indicates SUCCESS - * -1 indicates FAILURE - */ -extern int -__get_page(HTAB *hashp, - char * p, - uint32 bucket, - int is_bucket, - int is_disk, - int is_bitmap) -{ - register int fd, page; - size_t size; - int rsize; - uint16 *bp; - - fd = hashp->fp; - size = hashp->BSIZE; - - if ((fd == -1) || !is_disk) { - PAGE_INIT(p); - return (0); - } - if (is_bucket) - page = BUCKET_TO_PAGE(bucket); - else - page = OADDR_TO_PAGE(bucket); - if ((MY_LSEEK(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) || - ((rsize = read(fd, p, size)) == -1)) - return (-1); - - bp = (uint16 *)p; - if (!rsize) - bp[0] = 0; /* We hit the EOF, so initialize a new page */ - else - if ((unsigned)rsize != size) { - errno = EFTYPE; - return (-1); - } - - if (!is_bitmap && !bp[0]) { - PAGE_INIT(p); - } else { - -#ifdef DEBUG - if(BYTE_ORDER == LITTLE_ENDIAN) - { - int is_little_endian; - is_little_endian = BYTE_ORDER; - } - else if(BYTE_ORDER == BIG_ENDIAN) - { - int is_big_endian; - is_big_endian = BYTE_ORDER; - } - else - { - assert(0); - } -#endif - - if (hashp->LORDER != BYTE_ORDER) { - register int i, max; - - if (is_bitmap) { - max = hashp->BSIZE >> 2; /* divide by 4 */ - for (i = 0; i < max; i++) - M_32_SWAP(((int *)p)[i]); - } else { - M_16_SWAP(bp[0]); - max = bp[0] + 2; - - /* bound the size of max by - * the maximum number of entries - * in the array - */ - if((unsigned)max > (size / sizeof(uint16))) - return(DATABASE_CORRUPTED_ERROR); - - /* do the byte order swap - */ - for (i = 1; i <= max; i++) - M_16_SWAP(bp[i]); - } - } - - /* check the validity of the page here - * (after doing byte order swaping if necessary) - */ - if(!is_bitmap && bp[0] != 0) - { - uint16 num_keys = bp[0]; - uint16 offset; - uint16 i; - - /* bp[0] is supposed to be the number of - * entries currently in the page. If - * bp[0] is too large (larger than the whole - * page) then the page is corrupted - */ - if(bp[0] > (size / sizeof(uint16))) - return(DATABASE_CORRUPTED_ERROR); - - /* bound free space */ - if(FREESPACE(bp) > size) - return(DATABASE_CORRUPTED_ERROR); - - /* check each key and data offset to make - * sure they are all within bounds they - * should all be less than the previous - * offset as well. - */ - offset = size; - for(i=1 ; i <= num_keys; i+=2) - { - /* ignore overflow pages etc. */ - if(bp[i+1] >= REAL_KEY) - { - - if(bp[i] > offset || bp[i+1] > bp[i]) - return(DATABASE_CORRUPTED_ERROR); - - offset = bp[i+1]; - } - else - { - /* there are no other valid keys after - * seeing a non REAL_KEY - */ - break; - } - } - } - } - return (0); -} - -/* - * Write page p to disk - * - * Returns: - * 0 ==> OK - * -1 ==>failure - */ -extern int -__put_page(HTAB *hashp, char *p, uint32 bucket, int is_bucket, int is_bitmap) -{ - register int fd, page; - size_t size; - int wsize; - off_t offset; - - size = hashp->BSIZE; - if ((hashp->fp == -1) && open_temp(hashp)) - return (-1); - fd = hashp->fp; - - if (hashp->LORDER != BYTE_ORDER) { - register int i; - register int max; - - if (is_bitmap) { - max = hashp->BSIZE >> 2; /* divide by 4 */ - for (i = 0; i < max; i++) - M_32_SWAP(((int *)p)[i]); - } else { - max = ((uint16 *)p)[0] + 2; - - /* bound the size of max by - * the maximum number of entries - * in the array - */ - if((unsigned)max > (size / sizeof(uint16))) - return(DATABASE_CORRUPTED_ERROR); - - for (i = 0; i <= max; i++) - M_16_SWAP(((uint16 *)p)[i]); - - } - } - - if (is_bucket) - page = BUCKET_TO_PAGE(bucket); - else - page = OADDR_TO_PAGE(bucket); - offset = (off_t)page << hashp->BSHIFT; - if ((MY_LSEEK(fd, offset, SEEK_SET) == -1) || - ((wsize = write(fd, p, size)) == -1)) - /* Errno is set */ - return (-1); - if ((unsigned)wsize != size) { - errno = EFTYPE; - return (-1); - } -#if defined(_WIN32) || defined(_WINDOWS) - if (offset + size > hashp->file_size) { - hashp->updateEOF = 1; - } -#endif - /* put the page back the way it was so that it isn't byteswapped - * if it remains in memory - LJM - */ - if (hashp->LORDER != BYTE_ORDER) { - register int i; - register int max; - - if (is_bitmap) { - max = hashp->BSIZE >> 2; /* divide by 4 */ - for (i = 0; i < max; i++) - M_32_SWAP(((int *)p)[i]); - } else { - uint16 *bp = (uint16 *)p; - - M_16_SWAP(bp[0]); - max = bp[0] + 2; - - /* no need to bound the size if max again - * since it was done already above - */ - - /* do the byte order re-swap - */ - for (i = 1; i <= max; i++) - M_16_SWAP(bp[i]); - } - } - - return (0); -} - -#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1) -/* - * Initialize a new bitmap page. Bitmap pages are left in memory - * once they are read in. - */ -extern int -__ibitmap(HTAB *hashp, int pnum, int nbits, int ndx) -{ - uint32 *ip; - size_t clearbytes, clearints; - - if ((ip = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL) - return (1); - hashp->nmaps++; - clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1; - clearbytes = clearints << INT_TO_BYTE; - (void)memset((char *)ip, 0, clearbytes); - (void)memset(((char *)ip) + clearbytes, 0xFF, - hashp->BSIZE - clearbytes); - ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK); - SETBIT(ip, 0); - hashp->BITMAPS[ndx] = (uint16)pnum; - hashp->mapp[ndx] = ip; - return (0); -} - -static uint32 -first_free(uint32 map) -{ - register uint32 i, mask; - - mask = 0x1; - for (i = 0; i < BITS_PER_MAP; i++) { - if (!(mask & map)) - return (i); - mask = mask << 1; - } - return (i); -} - -static uint16 -overflow_page(HTAB *hashp) -{ - register uint32 *freep=NULL; - register int max_free, offset, splitnum; - uint16 addr; - uint32 i; - int bit, first_page, free_bit, free_page, in_use_bits, j; -#ifdef DEBUG2 - int tmp1, tmp2; -#endif - splitnum = hashp->OVFL_POINT; - max_free = hashp->SPARES[splitnum]; - - free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT); - free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1); - - /* 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 <= (unsigned)free_page; i++ ) { - if (!(freep = (uint32 *)hashp->mapp[i]) && - !(freep = fetch_bitmap(hashp, i))) - return (0); - if (i == (unsigned)free_page) - in_use_bits = free_bit; - else - in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1; - - if (i == (unsigned)first_page) { - bit = hashp->LAST_FREED & - ((hashp->BSIZE << BYTE_SHIFT) - 1); - j = bit / BITS_PER_MAP; - bit = bit & ~(BITS_PER_MAP - 1); - } else { - bit = 0; - j = 0; - } - for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP) - if (freep[j] != ALL_SET) - goto found; - } - - /* No Free Page Found */ - hashp->LAST_FREED = hashp->SPARES[splitnum]; - hashp->SPARES[splitnum]++; - offset = hashp->SPARES[splitnum] - - (splitnum ? hashp->SPARES[splitnum - 1] : 0); - -#define OVMSG "HASH: Out of overflow pages. Increase page size\n" - if (offset > SPLITMASK) { - if (++splitnum >= NCACHED) { -#ifndef macintosh - (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); -#endif - return (0); - } - hashp->OVFL_POINT = splitnum; - hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; - hashp->SPARES[splitnum-1]--; - offset = 1; - } - - /* Check if we need to allocate a new bitmap page */ - if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) { - free_page++; - if (free_page >= NCACHED) { -#ifndef macintosh - (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); -#endif - return (0); - } - /* - * This is tricky. The 1 indicates that you want the new page - * allocated with 1 clear bit. Actually, you are going to - * allocate 2 pages from this map. The first is going to be - * the map page, the second is the overflow page we were - * looking for. The init_bitmap routine automatically, sets - * the first bit of itself to indicate that the bitmap itself - * is in use. We would explicitly set the second bit, but - * don't have to if we tell init_bitmap not to leave it clear - * in the first place. - */ - if (__ibitmap(hashp, - (int)OADDR_OF(splitnum, offset), 1, free_page)) - return (0); - hashp->SPARES[splitnum]++; -#ifdef DEBUG2 - free_bit = 2; -#endif - offset++; - if (offset > SPLITMASK) { - if (++splitnum >= NCACHED) { -#ifndef macintosh - (void)write(STDERR_FILENO, OVMSG, - sizeof(OVMSG) - 1); -#endif - return (0); - } - hashp->OVFL_POINT = splitnum; - hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; - hashp->SPARES[splitnum-1]--; - offset = 0; - } - } else { - /* - * Free_bit addresses the last used bit. Bump it to address - * the first available bit. - */ - free_bit++; - SETBIT(freep, free_bit); - } - - /* Calculate address of the new overflow page */ - addr = OADDR_OF(splitnum, offset); -#ifdef DEBUG2 - (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", - addr, free_bit, free_page); -#endif - return (addr); - -found: - bit = bit + first_free(freep[j]); - SETBIT(freep, bit); -#ifdef DEBUG2 - tmp1 = bit; - tmp2 = i; -#endif - /* - * Bits are addressed starting with 0, but overflow pages are addressed - * beginning at 1. Bit is a bit addressnumber, so we need to increment - * it to convert it to a page number. - */ - bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT)); - if (bit >= hashp->LAST_FREED) - hashp->LAST_FREED = bit - 1; - - /* Calculate the split number for this page */ - for (i = 0; (i < (unsigned)splitnum) && (bit > hashp->SPARES[i]); i++) {} - offset = (i ? bit - hashp->SPARES[i - 1] : bit); - if (offset >= SPLITMASK) - 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", - addr, tmp1, tmp2); -#endif - - /* Allocate and return the overflow page */ - return (addr); -} - -/* - * Mark this overflow page as free. - */ -extern void -__free_ovflpage(HTAB *hashp, BUFHEAD *obufp) -{ - uint16 addr; - uint32 *freep; - uint32 bit_address, free_page, free_bit; - uint16 ndx; - - if(!obufp || !obufp->addr) - return; - - addr = obufp->addr; -#ifdef DEBUG1 - (void)fprintf(stderr, "Freeing %d\n", addr); -#endif - ndx = (((uint16)addr) >> SPLITSHIFT); - bit_address = - (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1; - if (bit_address < (unsigned)hashp->LAST_FREED) - hashp->LAST_FREED = bit_address; - free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT)); - free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1); - - if (!(freep = hashp->mapp[free_page])) - freep = fetch_bitmap(hashp, free_page); - -#ifdef DEBUG - /* - * This had better never happen. It means we tried to read a bitmap - * that has already had overflow pages allocated off it, and we - * failed to read it from the file. - */ - if (!freep) - { - assert(0); - return; - } -#endif - CLRBIT(freep, free_bit); -#ifdef DEBUG2 - (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n", - obufp->addr, free_bit, free_page); -#endif - __reclaim_buf(hashp, obufp); -} - -/* - * Returns: - * 0 success - * -1 failure - */ -static int -open_temp(HTAB *hashp) -{ -#ifdef XP_OS2 - hashp->fp = mkstemp(NULL); -#else -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) - sigset_t set, oset; -#endif - char * tmpdir; - int len; - static const char namestr[] = "/_hashXXXXXX"; - char filename[1024]; - char last; - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) - /* Block signals; make sure file goes away at process exit. */ - (void)sigfillset(&set); - (void)sigprocmask(SIG_BLOCK, &set, &oset); -#endif - - filename[0] = 0; -#if defined(macintosh) - strcat(filename, namestr + 1); -#else - tmpdir = getenv("TMP"); - if (!tmpdir) - tmpdir = getenv("TMPDIR"); - if (!tmpdir) - tmpdir = getenv("TEMP"); - if (!tmpdir) - tmpdir = "."; - len = strlen(tmpdir); - if (len && len < (sizeof filename - sizeof namestr)) { - strcpy(filename, tmpdir); - } - len = strlen(filename); - last = tmpdir[len - 1]; - strcat(filename, (last == '/' || last == '\\') ? namestr + 1 : namestr); -#endif - -#if defined(_WIN32) || defined(_WINDOWS) - if ((hashp->fp = mkstempflags(filename, _O_BINARY|_O_TEMPORARY)) != -1) { - if (hashp->filename) { - free(hashp->filename); - } - hashp->filename = strdup(filename); - hashp->is_temp = 1; - } -#else - if ((hashp->fp = mkstemp(filename)) != -1) { - (void)unlink(filename); -#if !defined(macintosh) - (void)fcntl(hashp->fp, F_SETFD, 1); -#endif - } -#endif - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) - (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); -#endif -#endif /* !OS2 */ - return (hashp->fp != -1 ? 0 : -1); -} - -/* - * We have to know that the key will fit, but the last entry on the page is - * an overflow pair, so we need to shift things. - */ -static void -squeeze_key(uint16 *sp, const DBT * key, const DBT * val) -{ - register char *p; - uint16 free_space, n, off, pageno; - - p = (char *)sp; - n = sp[0]; - free_space = FREESPACE(sp); - off = OFFSET(sp); - - pageno = sp[n - 1]; - off -= key->size; - sp[n - 1] = off; - memmove(p + off, key->data, key->size); - off -= val->size; - sp[n] = off; - memmove(p + off, val->data, val->size); - sp[0] = n + 2; - sp[n + 1] = pageno; - sp[n + 2] = OVFLPAGE; - FREESPACE(sp) = free_space - PAIRSIZE(key, val); - OFFSET(sp) = off; -} - -static uint32 * -fetch_bitmap(HTAB *hashp, uint32 ndx) -{ - if (ndx >= (unsigned)hashp->nmaps) - return (NULL); - if ((hashp->mapp[ndx] = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL) - return (NULL); - if (__get_page(hashp, - (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) { - free(hashp->mapp[ndx]); - hashp->mapp[ndx] = NULL; /* NEW: 9-11-95 */ - return (NULL); - } - return (hashp->mapp[ndx]); -} - -#ifdef DEBUG4 -int -print_chain(int addr) -{ - BUFHEAD *bufp; - short *bp, oaddr; - - (void)fprintf(stderr, "%d ", addr); - bufp = __get_buf(hashp, addr, NULL, 0); - bp = (short *)bufp->page; - while (bp[0] && ((bp[bp[0]] == OVFLPAGE) || - ((bp[0] > 2) && bp[2] < REAL_KEY))) { - oaddr = bp[bp[0] - 1]; - (void)fprintf(stderr, "%d ", (int)oaddr); - bufp = __get_buf(hashp, (int)oaddr, bufp, 0); - bp = (short *)bufp->page; - } - (void)fprintf(stderr, "\n"); -} -#endif diff --git a/dbm/src/hash.c b/dbm/src/hash.c deleted file mode 100644 index 8be75721b..000000000 --- a/dbm/src/hash.c +++ /dev/null @@ -1,1258 +0,0 @@ -/*- - * 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 - * Margo Seltzer. - * - * 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[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP) -#include <sys/param.h> -#endif - -#if !defined(macintosh) -#ifdef XP_OS2_EMX -#include <sys/types.h> -#endif -#include <sys/stat.h> -#endif - -#if defined(macintosh) -#include <unix.h> -#include <unistd.h> -#endif - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP) -#include <unistd.h> -#endif -#if defined(_WIN32) || defined(_WINDOWS) -#include <windows.h> -#endif - -#ifdef XP_OS2_VACPP -#include "types.h" -#define EPERM SOCEPERM -#endif - -#include <assert.h> - -#include "mcom_db.h" -#include "hash.h" -#include "page.h" - -/* -#include "extern.h" -*/ -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 *, uint)); -static int hash_fd __P((const DB *)); -static int hash_get __P((const DB *, const DBT *, DBT *, uint)); -static int hash_put __P((const DB *, DBT *, const DBT *, uint)); -static void *hash_realloc __P((SEGMENT **, size_t, size_t)); -static int hash_seq __P((const DB *, DBT *, DBT *, uint)); -static int hash_sync __P((const DB *, uint)); -static int hdestroy __P((HTAB *)); -static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *)); -static int init_htab __P((HTAB *, int)); -#if BYTE_ORDER == LITTLE_ENDIAN -static void swap_header __P((HTAB *)); -static void swap_header_copy __P((HASHHDR *, HASHHDR *)); -#endif - -/* Fast arithmetic, relying on powers of 2, */ -#define MOD(x, y) ((x) & ((y) - 1)) - -#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; } - -/* Return values */ -#define SUCCESS (0) -#define DBM_ERROR (-1) -#define ABNORMAL (1) - -#ifdef HASH_STATISTICS -int hash_accesses, hash_collisions, hash_expansions, hash_overflows; -#endif - -/* A new Lou (montulli@mozilla.com) routine. - * - * The database is screwed. - * - * This closes the file, flushing buffers as appropriate. - */ -static void -__remove_database(DB *dbp) -{ - HTAB *hashp = (HTAB *)dbp->internal; - - assert(0); - - if (!hashp) - return; - hdestroy(hashp); - dbp->internal = NULL; -} - -/************************** INTERFACE ROUTINES ***************************/ -/* OPEN/CLOSE */ - - -extern DB * -__hash_open(const char *file, int flags, int mode, const HASHINFO *info, int dflags) -{ - HTAB *hashp=NULL; - struct stat statbuf; - DB *dbp; - int bpages, hdrsize, new_table, nsegs, save_errno; - - if ((flags & O_ACCMODE) == O_WRONLY) { - errno = EINVAL; - RETURN_ERROR(ENOMEM, error0); - } - - /* zero the statbuffer so that - * we can check it for a non-zero - * date to see if stat succeeded - */ - memset(&statbuf, 0, sizeof(struct stat)); - - if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) - RETURN_ERROR(ENOMEM, error0); - hashp->fp = NO_FILE; - if(file) - hashp->filename = strdup(file); - - /* - * Even if user wants write only, we need to be able to read - * the actual file, so we need to open it read/write. But, the - * field in the hashp structure needs to be accurate so that - * we can check accesses. - */ - hashp->flags = flags; - - new_table = 0; - if (!file || (flags & O_TRUNC) || (stat(file, &statbuf) && (errno == ENOENT))) - { - if (errno == ENOENT) - errno = 0; /* Just in case someone looks at errno */ - new_table = 1; - } - else if(statbuf.st_mtime && statbuf.st_size == 0) - { - /* check for a zero length file and delete it - * if it exists - */ - new_table = 1; - } - hashp->file_size = statbuf.st_size; - - if (file) { - -#if defined(_WIN32) || defined(_WINDOWS) || defined (macintosh) || defined(XP_OS2_VACPP) - if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1) - RETURN_ERROR(errno, error0); -#else - if ((hashp->fp = open(file, flags, mode)) == -1) - RETURN_ERROR(errno, error0); - (void)fcntl(hashp->fp, F_SETFD, 1); -/* We can't use fcntl because of NFS bugs. SIGH */ -#if 0 - { - struct flock fl; - memset(&fl, 0, sizeof(fl)); - fl.l_type = F_WRLCK; - if (fcntl(hashp->fp, F_SETLK, &fl) < 0) { -#ifdef DEBUG - fprintf(stderr, "unable to open %s because it's locked (flags=0x%x)\n", file, flags); -#endif - RETURN_ERROR(EACCES, error1); - } - } -#endif - -#endif - } - if (new_table) { - if (!init_hash(hashp, file, (HASHINFO *)info)) - RETURN_ERROR(errno, error1); - } else { - /* Table already exists */ - if (info && info->hash) - hashp->hash = info->hash; - else - hashp->hash = __default_hash; - - hdrsize = read(hashp->fp, (char *)&hashp->hdr, sizeof(HASHHDR)); -#if BYTE_ORDER == LITTLE_ENDIAN - swap_header(hashp); -#endif - if (hdrsize == -1) - RETURN_ERROR(errno, error1); - if (hdrsize != sizeof(HASHHDR)) - RETURN_ERROR(EFTYPE, error1); - /* Verify file type, versions and hash function */ - if (hashp->MAGIC != HASHMAGIC) - RETURN_ERROR(EFTYPE, error1); -#define OLDHASHVERSION 1 - if (hashp->VERSION != HASHVERSION && - hashp->VERSION != OLDHASHVERSION) - RETURN_ERROR(EFTYPE, error1); - if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != (unsigned)hashp->H_CHARKEY) - RETURN_ERROR(EFTYPE, error1); - if (hashp->NKEYS < 0) { - /* - ** OOPS. Old bad database from previously busted - ** code. Blow it away. - */ - close(hashp->fp); - if (remove(file) < 0) { -#if defined(DEBUG) && defined(XP_UNIX) - fprintf(stderr, - "WARNING: You have an old bad cache.db file" - " '%s', and I couldn't remove it!\n", file); -#endif - } else { -#if defined(DEBUG) && defined(XP_UNIX) - fprintf(stderr, - "WARNING: I blew away your %s file because" - " it was bad due to a recently fixed bug\n", - file); -#endif - } - RETURN_ERROR(ENOENT, error0); - } - - /* - * Figure out how many segments we need. Max_Bucket is the - * maximum bucket number, so the number of buckets is - * max_bucket + 1. - */ - nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) / - hashp->SGSIZE; - hashp->nsegs = 0; - if (alloc_segs(hashp, nsegs)) - /* - * If alloc_segs fails, table will have been destroyed - * and errno will have been set. - */ - RETURN_ERROR(ENOMEM, error0); - /* Read in bitmaps */ - bpages = (hashp->SPARES[hashp->OVFL_POINT] + - (hashp->BSIZE << BYTE_SHIFT) - 1) >> - (hashp->BSHIFT + BYTE_SHIFT); - - hashp->nmaps = bpages; - (void)memset(&hashp->mapp[0], 0, bpages * sizeof(uint32 *)); - } - - /* Initialize Buffer Manager */ - if (info && info->cachesize) - __buf_init(hashp, (int32) info->cachesize); - else - __buf_init(hashp, DEF_BUFSIZE); - - hashp->new_file = new_table; -#ifdef macintosh - hashp->save_file = file && !(hashp->flags & O_RDONLY); -#else - hashp->save_file = file && (hashp->flags & O_RDWR); -#endif - hashp->cbucket = -1; - if (!(dbp = (DB *)malloc(sizeof(DB)))) { - save_errno = errno; - hdestroy(hashp); - errno = save_errno; - RETURN_ERROR(ENOMEM, error0); - } - dbp->internal = hashp; - dbp->close = hash_close; - dbp->del = hash_delete; - dbp->fd = hash_fd; - dbp->get = hash_get; - dbp->put = hash_put; - dbp->seq = hash_seq; - dbp->sync = hash_sync; - dbp->type = DB_HASH; - -#if 0 -#if defined(DEBUG) && !defined(_WINDOWS) -{ -extern int MKLib_trace_flag; - - if(MKLib_trace_flag) - (void)fprintf(stderr, -"%s\n%s%lx\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n", - "init_htab:", - "TABLE POINTER ", (unsigned long) hashp, - "BUCKET SIZE ", hashp->BSIZE, - "BUCKET SHIFT ", hashp->BSHIFT, - "DIRECTORY SIZE ", hashp->DSIZE, - "SEGMENT SIZE ", hashp->SGSIZE, - "SEGMENT SHIFT ", hashp->SSHIFT, - "FILL FACTOR ", hashp->FFACTOR, - "MAX BUCKET ", hashp->MAX_BUCKET, - "OVFL POINT ", hashp->OVFL_POINT, - "LAST FREED ", hashp->LAST_FREED, - "HIGH MASK ", hashp->HIGH_MASK, - "LOW MASK ", hashp->LOW_MASK, - "NSEGS ", hashp->nsegs, - "NKEYS ", hashp->NKEYS); -} -#endif -#endif /* 0 */ -#ifdef HASH_STATISTICS - hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0; -#endif - return (dbp); - -error1: - if (hashp != NULL) - (void)close(hashp->fp); - -error0: - free(hashp); - errno = save_errno; - return (NULL); -} - -static int -hash_close(DB *dbp) -{ - HTAB *hashp; - int retval; - - if (!dbp) - return (DBM_ERROR); - - hashp = (HTAB *)dbp->internal; - if(!hashp) - return (DBM_ERROR); - - retval = hdestroy(hashp); - free(dbp); - return (retval); -} - -static int hash_fd(const DB *dbp) -{ - HTAB *hashp; - - if (!dbp) - return (DBM_ERROR); - - hashp = (HTAB *)dbp->internal; - if(!hashp) - return (DBM_ERROR); - - if (hashp->fp == -1) { - errno = ENOENT; - return (-1); - } - return (hashp->fp); -} - -/************************** LOCAL CREATION ROUTINES **********************/ -static HTAB * -init_hash(HTAB *hashp, const char *file, HASHINFO *info) -{ - struct stat statbuf; - int nelem; - - nelem = 1; - hashp->NKEYS = 0; - hashp->LORDER = BYTE_ORDER; - hashp->BSIZE = DEF_BUCKET_SIZE; - hashp->BSHIFT = DEF_BUCKET_SHIFT; - hashp->SGSIZE = DEF_SEGSIZE; - hashp->SSHIFT = DEF_SEGSIZE_SHIFT; - hashp->DSIZE = DEF_DIRSIZE; - hashp->FFACTOR = DEF_FFACTOR; - hashp->hash = __default_hash; - memset(hashp->SPARES, 0, sizeof(hashp->SPARES)); - memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS)); - - /* Fix bucket size to be optimal for file system */ - if (file != NULL) { - if (stat(file, &statbuf)) - return (NULL); - -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(VMS) && !defined(XP_OS2) -#ifdef __QNX__ - hashp->BSIZE = statbuf.st_size; -#else - hashp->BSIZE = statbuf.st_blksize; -#endif - - /* new code added by Lou to reduce block - * size down below MAX_BSIZE - */ - if (hashp->BSIZE > MAX_BSIZE) - hashp->BSIZE = MAX_BSIZE; -#endif - hashp->BSHIFT = __log2((uint32)hashp->BSIZE); - } - - if (info) { - if (info->bsize) { - /* Round pagesize up to power of 2 */ - hashp->BSHIFT = __log2(info->bsize); - hashp->BSIZE = 1 << hashp->BSHIFT; - if (hashp->BSIZE > MAX_BSIZE) { - errno = EINVAL; - return (NULL); - } - } - if (info->ffactor) - hashp->FFACTOR = info->ffactor; - if (info->hash) - hashp->hash = info->hash; - if (info->nelem) - nelem = info->nelem; - if (info->lorder) { - if (info->lorder != BIG_ENDIAN && - info->lorder != LITTLE_ENDIAN) { - errno = EINVAL; - return (NULL); - } - hashp->LORDER = info->lorder; - } - } - /* init_htab should destroy the table and set errno if it fails */ - if (init_htab(hashp, nelem)) - return (NULL); - else - return (hashp); -} -/* - * This calls alloc_segs which may run out of memory. Alloc_segs will destroy - * the table and set errno, so we just pass the error information along. - * - * Returns 0 on No Error - */ -static int -init_htab(HTAB *hashp, int nelem) -{ - register int nbuckets, nsegs; - int l2; - - /* - * Divide number of elements by the fill factor and determine a - * desired number of buckets. Allocate space for the next greater - * power of two number of buckets. - */ - nelem = (nelem - 1) / hashp->FFACTOR + 1; - - l2 = __log2((uint32)PR_MAX(nelem, 2)); - nbuckets = 1 << l2; - - hashp->SPARES[l2] = l2 + 1; - hashp->SPARES[l2 + 1] = l2 + 1; - hashp->OVFL_POINT = l2; - hashp->LAST_FREED = 2; - - /* First bitmap page is at: splitpoint l2 page offset 1 */ - if (__ibitmap(hashp, (int)OADDR_OF(l2, 1), l2 + 1, 0)) - return (-1); - - hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1; - hashp->HIGH_MASK = (nbuckets << 1) - 1; - hashp->HDRPAGES = ((PR_MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >> - hashp->BSHIFT) + 1; - - nsegs = (nbuckets - 1) / hashp->SGSIZE + 1; - nsegs = 1 << __log2((uint32)nsegs); - - if (nsegs > hashp->DSIZE) - hashp->DSIZE = nsegs; - return (alloc_segs(hashp, nsegs)); -} - -/********************** DESTROY/CLOSE ROUTINES ************************/ - -/* - * Flushes any changes to the file if necessary and destroys the hashp - * structure, freeing all allocated space. - */ -static int -hdestroy(HTAB *hashp) -{ - int i, save_errno; - - save_errno = 0; - -#ifdef HASH_STATISTICS - (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n", - hash_accesses, hash_collisions); - (void)fprintf(stderr, "hdestroy: expansions %ld\n", - hash_expansions); - (void)fprintf(stderr, "hdestroy: overflows %ld\n", - hash_overflows); - (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n", - hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs); - - for (i = 0; i < NCACHED; i++) - (void)fprintf(stderr, - "spares[%d] = %d\n", i, hashp->SPARES[i]); -#endif - /* - * Call on buffer manager to free buffers, and if required, - * write them to disk. - */ - if (__buf_free(hashp, 1, hashp->save_file)) - save_errno = errno; - if (hashp->dir) { - free(*hashp->dir); /* Free initial segments */ - /* Free extra segments */ - while (hashp->exsegs--) - free(hashp->dir[--hashp->nsegs]); - free(hashp->dir); - } - if (flush_meta(hashp) && !save_errno) - save_errno = errno; - /* Free Bigmaps */ - for (i = 0; i < hashp->nmaps; i++) - if (hashp->mapp[i]) - free(hashp->mapp[i]); - - if (hashp->fp != -1) - (void)close(hashp->fp); - - if(hashp->filename) { -#if defined(_WIN32) || defined(_WINDOWS) || defined(XP_OS2) - if (hashp->is_temp) - (void)unlink(hashp->filename); -#endif - free(hashp->filename); - } - - free(hashp); - - if (save_errno) { - errno = save_errno; - return (DBM_ERROR); - } - return (SUCCESS); -} - -#if defined(_WIN32) || defined(_WINDOWS) -/* - * Close and reopen file to force file length update on windows. - * - * Returns: - * 0 == OK - * -1 DBM_ERROR - */ -static int -update_EOF(HTAB *hashp) -{ -#if defined(DBM_REOPEN_ON_FLUSH) - char * file = hashp->filename; - off_t file_size; - int flags; - int mode = -1; - struct stat statbuf; - - memset(&statbuf, 0, sizeof statbuf); - - /* make sure we won't lose the file by closing it. */ - if (!file || (stat(file, &statbuf) && (errno == ENOENT))) { - /* pretend we did it. */ - return 0; - } - - (void)close(hashp->fp); - - flags = hashp->flags & ~(O_TRUNC | O_CREAT | O_EXCL); - - if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1) - return -1; - file_size = lseek(hashp->fp, (off_t)0, SEEK_END); - if (file_size == -1) - return -1; - hashp->file_size = file_size; - return 0; -#else - int fd = hashp->fp; - off_t file_size = lseek(fd, (off_t)0, SEEK_END); - HANDLE handle = (HANDLE)_get_osfhandle(fd); - BOOL cool = FlushFileBuffers(handle); -#ifdef DEBUG3 - if (!cool) { - DWORD err = GetLastError(); - (void)fprintf(stderr, - "FlushFileBuffers failed, last error = %d, 0x%08x\n", - err, err); - } -#endif - if (file_size == -1) - return -1; - hashp->file_size = file_size; - return cool ? 0 : -1; -#endif -} -#endif - -/* - * Write modified pages to disk - * - * Returns: - * 0 == OK - * -1 DBM_ERROR - */ -static int -hash_sync(const DB *dbp, uint flags) -{ - HTAB *hashp; - - if (flags != 0) { - errno = EINVAL; - return (DBM_ERROR); - } - - if (!dbp) - return (DBM_ERROR); - - hashp = (HTAB *)dbp->internal; - if(!hashp) - return (DBM_ERROR); - - if (!hashp->save_file) - return (0); - if (__buf_free(hashp, 0, 1) || flush_meta(hashp)) - return (DBM_ERROR); -#if defined(_WIN32) || defined(_WINDOWS) - if (hashp->updateEOF && hashp->filename && !hashp->is_temp) { - int status = update_EOF(hashp); - hashp->updateEOF = 0; - if (status) - return status; - } -#endif - hashp->new_file = 0; - return (0); -} - -/* - * Returns: - * 0 == OK - * -1 indicates that errno should be set - */ -static int -flush_meta(HTAB *hashp) -{ - HASHHDR *whdrp; -#if BYTE_ORDER == LITTLE_ENDIAN - HASHHDR whdr; -#endif - int fp, i, wsize; - - if (!hashp->save_file) - return (0); - hashp->MAGIC = HASHMAGIC; - hashp->VERSION = HASHVERSION; - hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY)); - - fp = hashp->fp; - whdrp = &hashp->hdr; -#if BYTE_ORDER == LITTLE_ENDIAN - whdrp = &whdr; - swap_header_copy(&hashp->hdr, whdrp); -#endif - if ((lseek(fp, (off_t)0, SEEK_SET) == -1) || - ((wsize = write(fp, (char*)whdrp, sizeof(HASHHDR))) == -1)) - return (-1); - else - if (wsize != sizeof(HASHHDR)) { - errno = EFTYPE; - hashp->dbmerrno = errno; - return (-1); - } - for (i = 0; i < NCACHED; i++) - if (hashp->mapp[i]) - if (__put_page(hashp, (char *)hashp->mapp[i], - hashp->BITMAPS[i], 0, 1)) - return (-1); - return (0); -} - -/*******************************SEARCH ROUTINES *****************************/ -/* - * All the access routines return - * - * Returns: - * 0 on SUCCESS - * 1 to indicate an external DBM_ERROR (i.e. key not found, etc) - * -1 to indicate an internal DBM_ERROR (i.e. out of memory, etc) - */ -static int -hash_get( - const DB *dbp, - const DBT *key, - DBT *data, - uint flag) -{ - HTAB *hashp; - int rv; - - hashp = (HTAB *)dbp->internal; - if (!hashp) - return (DBM_ERROR); - - if (flag) { - hashp->dbmerrno = errno = EINVAL; - return (DBM_ERROR); - } - - rv = hash_access(hashp, HASH_GET, (DBT *)key, data); - - if(rv == DATABASE_CORRUPTED_ERROR) - { -#if defined(unix) && defined(DEBUG) - printf("\n\nDBM Database has been corrupted, tell Lou...\n\n"); -#endif - __remove_database((DB *)dbp); - } - - return(rv); -} - -static int -hash_put( - const DB *dbp, - DBT *key, - const DBT *data, - uint flag) -{ - HTAB *hashp; - int rv; - - hashp = (HTAB *)dbp->internal; - if (!hashp) - return (DBM_ERROR); - - if (flag && flag != R_NOOVERWRITE) { - hashp->dbmerrno = errno = EINVAL; - return (DBM_ERROR); - } - if ((hashp->flags & O_ACCMODE) == O_RDONLY) { - hashp->dbmerrno = errno = EPERM; - return (DBM_ERROR); - } - - rv = hash_access(hashp, flag == R_NOOVERWRITE ? - HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data); - - if(rv == DATABASE_CORRUPTED_ERROR) - { -#if defined(unix) && defined(DEBUG) - printf("\n\nDBM Database has been corrupted, tell Lou...\n\n"); -#endif - __remove_database((DB *)dbp); - } - - return(rv); -} - -static int -hash_delete( - const DB *dbp, - const DBT *key, - uint flag) /* Ignored */ -{ - HTAB *hashp; - int rv; - - hashp = (HTAB *)dbp->internal; - if (!hashp) - return (DBM_ERROR); - - if (flag && flag != R_CURSOR) { - hashp->dbmerrno = errno = EINVAL; - return (DBM_ERROR); - } - if ((hashp->flags & O_ACCMODE) == O_RDONLY) { - hashp->dbmerrno = errno = EPERM; - return (DBM_ERROR); - } - rv = hash_access(hashp, HASH_DELETE, (DBT *)key, NULL); - - if(rv == DATABASE_CORRUPTED_ERROR) - { -#if defined(unix) && defined(DEBUG) - printf("\n\nDBM Database has been corrupted, tell Lou...\n\n"); -#endif - __remove_database((DB *)dbp); - } - - return(rv); -} - -#define MAX_OVERFLOW_HASH_ACCESS_LOOPS 2000 -/* - * Assume that hashp has been set in wrapper routine. - */ -static int -hash_access( - HTAB *hashp, - ACTION action, - DBT *key, DBT *val) -{ - register BUFHEAD *rbufp; - BUFHEAD *bufp, *save_bufp; - register uint16 *bp; - register long n, ndx, off; - register size_t size; - register char *kp; - uint16 pageno; - uint32 ovfl_loop_count=0; - int32 last_overflow_page_no = -1; - -#ifdef HASH_STATISTICS - hash_accesses++; -#endif - - off = hashp->BSIZE; - size = key->size; - kp = (char *)key->data; - rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0); - if (!rbufp) - return (DATABASE_CORRUPTED_ERROR); - save_bufp = rbufp; - - /* Pin the bucket chain */ - rbufp->flags |= BUF_PIN; - for (bp = (uint16 *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) - { - - if (bp[1] >= REAL_KEY) { - /* Real key/data pair */ - if (size == (unsigned)(off - *bp) && - memcmp(kp, rbufp->page + *bp, size) == 0) - goto found; - off = bp[1]; -#ifdef HASH_STATISTICS - hash_collisions++; -#endif - bp += 2; - ndx += 2; - } else if (bp[1] == OVFLPAGE) { - - /* database corruption: overflow loop detection */ - if(last_overflow_page_no == (int32)*bp) - return (DATABASE_CORRUPTED_ERROR); - - last_overflow_page_no = *bp; - - rbufp = __get_buf(hashp, *bp, rbufp, 0); - if (!rbufp) { - save_bufp->flags &= ~BUF_PIN; - return (DBM_ERROR); - } - - ovfl_loop_count++; - if(ovfl_loop_count > MAX_OVERFLOW_HASH_ACCESS_LOOPS) - return (DATABASE_CORRUPTED_ERROR); - - /* FOR LOOP INIT */ - bp = (uint16 *)rbufp->page; - n = *bp++; - ndx = 1; - off = hashp->BSIZE; - } else if (bp[1] < REAL_KEY) { - if ((ndx = - __find_bigpair(hashp, rbufp, ndx, kp, (int)size)) > 0) - goto found; - if (ndx == -2) { - bufp = rbufp; - if (!(pageno = - __find_last_page(hashp, &bufp))) { - ndx = 0; - rbufp = bufp; - break; /* FOR */ - } - rbufp = __get_buf(hashp, pageno, bufp, 0); - if (!rbufp) { - save_bufp->flags &= ~BUF_PIN; - return (DBM_ERROR); - } - /* FOR LOOP INIT */ - bp = (uint16 *)rbufp->page; - n = *bp++; - ndx = 1; - off = hashp->BSIZE; - } else { - save_bufp->flags &= ~BUF_PIN; - return (DBM_ERROR); - - } - } - } - - /* Not found */ - switch (action) { - case HASH_PUT: - case HASH_PUTNEW: - if (__addel(hashp, rbufp, key, val)) { - save_bufp->flags &= ~BUF_PIN; - return (DBM_ERROR); - } else { - save_bufp->flags &= ~BUF_PIN; - return (SUCCESS); - } - case HASH_GET: - case HASH_DELETE: - default: - save_bufp->flags &= ~BUF_PIN; - return (ABNORMAL); - } - -found: - switch (action) { - case HASH_PUTNEW: - save_bufp->flags &= ~BUF_PIN; - return (ABNORMAL); - case HASH_GET: - bp = (uint16 *)rbufp->page; - if (bp[ndx + 1] < REAL_KEY) { - if (__big_return(hashp, rbufp, ndx, val, 0)) - return (DBM_ERROR); - } else { - val->data = (uint8 *)rbufp->page + (int)bp[ndx + 1]; - val->size = bp[ndx] - bp[ndx + 1]; - } - break; - case HASH_PUT: - if ((__delpair(hashp, rbufp, ndx)) || - (__addel(hashp, rbufp, key, val))) { - save_bufp->flags &= ~BUF_PIN; - return (DBM_ERROR); - } - break; - case HASH_DELETE: - if (__delpair(hashp, rbufp, ndx)) - return (DBM_ERROR); - break; - default: - abort(); - } - save_bufp->flags &= ~BUF_PIN; - return (SUCCESS); -} - -static int -hash_seq( - const DB *dbp, - DBT *key, DBT *data, - uint flag) -{ - register uint32 bucket; - register BUFHEAD *bufp; - HTAB *hashp; - uint16 *bp, ndx; - - hashp = (HTAB *)dbp->internal; - if (!hashp) - return (DBM_ERROR); - - if (flag && flag != R_FIRST && flag != R_NEXT) { - hashp->dbmerrno = errno = EINVAL; - return (DBM_ERROR); - } -#ifdef HASH_STATISTICS - hash_accesses++; -#endif - if ((hashp->cbucket < 0) || (flag == R_FIRST)) { - hashp->cbucket = 0; - hashp->cndx = 1; - hashp->cpage = NULL; - } - - for (bp = NULL; !bp || !bp[0]; ) { - if (!(bufp = hashp->cpage)) { - for (bucket = hashp->cbucket; - bucket <= (unsigned)hashp->MAX_BUCKET; - bucket++, hashp->cndx = 1) { - bufp = __get_buf(hashp, bucket, NULL, 0); - if (!bufp) - return (DBM_ERROR); - hashp->cpage = bufp; - bp = (uint16 *)bufp->page; - if (bp[0]) - break; - } - hashp->cbucket = bucket; - if (hashp->cbucket > hashp->MAX_BUCKET) { - hashp->cbucket = -1; - return (ABNORMAL); - } - } else - bp = (uint16 *)hashp->cpage->page; - -#ifdef DEBUG - assert(bp); - assert(bufp); -#endif - while (bp[hashp->cndx + 1] == OVFLPAGE) { - bufp = hashp->cpage = - __get_buf(hashp, bp[hashp->cndx], bufp, 0); - if (!bufp) - return (DBM_ERROR); - bp = (uint16 *)(bufp->page); - hashp->cndx = 1; - } - if (!bp[0]) { - hashp->cpage = NULL; - ++hashp->cbucket; - } - } - ndx = hashp->cndx; - if (bp[ndx + 1] < REAL_KEY) { - if (__big_keydata(hashp, bufp, key, data, 1)) - return (DBM_ERROR); - } else { - key->data = (uint8 *)hashp->cpage->page + bp[ndx]; - key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx]; - data->data = (uint8 *)hashp->cpage->page + bp[ndx + 1]; - data->size = bp[ndx] - bp[ndx + 1]; - ndx += 2; - if (ndx > bp[0]) { - hashp->cpage = NULL; - hashp->cbucket++; - hashp->cndx = 1; - } else - hashp->cndx = ndx; - } - return (SUCCESS); -} - -/********************************* UTILITIES ************************/ - -/* - * Returns: - * 0 ==> OK - * -1 ==> Error - */ -extern int -__expand_table(HTAB *hashp) -{ - uint32 old_bucket, new_bucket; - int new_segnum, spare_ndx; - size_t dirsize; - -#ifdef HASH_STATISTICS - hash_expansions++; -#endif - new_bucket = ++hashp->MAX_BUCKET; - old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK); - - new_segnum = new_bucket >> hashp->SSHIFT; - - /* Check if we need a new segment */ - if (new_segnum >= hashp->nsegs) { - /* Check if we need to expand directory */ - if (new_segnum >= hashp->DSIZE) { - /* Reallocate directory */ - dirsize = hashp->DSIZE * sizeof(SEGMENT *); - if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1)) - return (-1); - hashp->DSIZE = dirsize << 1; - } - if ((hashp->dir[new_segnum] = - (SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(SEGMENT))) == NULL) - return (-1); - hashp->exsegs++; - hashp->nsegs++; - } - /* - * If the split point is increasing (MAX_BUCKET's log base 2 - * * increases), we need to copy the current contents of the spare - * split bucket to the next bucket. - */ - spare_ndx = __log2((uint32)(hashp->MAX_BUCKET + 1)); - if (spare_ndx > hashp->OVFL_POINT) { - hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT]; - hashp->OVFL_POINT = spare_ndx; - } - - if (new_bucket > (unsigned)hashp->HIGH_MASK) { - /* Starting a new doubling */ - hashp->LOW_MASK = hashp->HIGH_MASK; - hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK; - } - /* Relocate records to the new bucket */ - return (__split_page(hashp, old_bucket, new_bucket)); -} - -/* - * If realloc guarantees that the pointer is not destroyed if the realloc - * fails, then this routine can go away. - */ -static void * -hash_realloc( - SEGMENT **p_ptr, - size_t oldsize, size_t newsize) -{ - register void *p; - - if ((p = malloc(newsize))) { - memmove(p, *p_ptr, oldsize); - memset((char *)p + oldsize, 0, newsize - oldsize); - free(*p_ptr); - *p_ptr = (SEGMENT *)p; - } - return (p); -} - -extern uint32 -__call_hash(HTAB *hashp, char *k, size_t len) -{ - uint32 n, bucket; - - n = hashp->hash(k, len); - bucket = n & hashp->HIGH_MASK; - if (bucket > (unsigned)hashp->MAX_BUCKET) - bucket = bucket & hashp->LOW_MASK; - return (bucket); -} - -/* - * Allocate segment table. On error, destroy the table and set errno. - * - * Returns 0 on success - */ -static int -alloc_segs( - HTAB *hashp, - int nsegs) -{ - register int i; - register SEGMENT store; - - int save_errno; - - if ((hashp->dir = - (SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT *))) == NULL) { - save_errno = errno; - (void)hdestroy(hashp); - errno = save_errno; - return (-1); - } - /* Allocate segments */ - if ((store = - (SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) { - save_errno = errno; - (void)hdestroy(hashp); - errno = save_errno; - return (-1); - } - for (i = 0; i < nsegs; i++, hashp->nsegs++) - hashp->dir[i] = &store[i << hashp->SSHIFT]; - return (0); -} - -#if BYTE_ORDER == LITTLE_ENDIAN -/* - * Hashp->hdr needs to be byteswapped. - */ -static void -swap_header_copy( - HASHHDR *srcp, HASHHDR *destp) -{ - int i; - - P_32_COPY(srcp->magic, destp->magic); - P_32_COPY(srcp->version, destp->version); - P_32_COPY(srcp->lorder, destp->lorder); - P_32_COPY(srcp->bsize, destp->bsize); - P_32_COPY(srcp->bshift, destp->bshift); - P_32_COPY(srcp->dsize, destp->dsize); - P_32_COPY(srcp->ssize, destp->ssize); - P_32_COPY(srcp->sshift, destp->sshift); - P_32_COPY(srcp->ovfl_point, destp->ovfl_point); - P_32_COPY(srcp->last_freed, destp->last_freed); - P_32_COPY(srcp->max_bucket, destp->max_bucket); - P_32_COPY(srcp->high_mask, destp->high_mask); - P_32_COPY(srcp->low_mask, destp->low_mask); - P_32_COPY(srcp->ffactor, destp->ffactor); - P_32_COPY(srcp->nkeys, destp->nkeys); - P_32_COPY(srcp->hdrpages, destp->hdrpages); - P_32_COPY(srcp->h_charkey, destp->h_charkey); - for (i = 0; i < NCACHED; i++) { - P_32_COPY(srcp->spares[i], destp->spares[i]); - P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]); - } -} - -static void -swap_header(HTAB *hashp) -{ - HASHHDR *hdrp; - int i; - - hdrp = &hashp->hdr; - - M_32_SWAP(hdrp->magic); - M_32_SWAP(hdrp->version); - M_32_SWAP(hdrp->lorder); - M_32_SWAP(hdrp->bsize); - M_32_SWAP(hdrp->bshift); - M_32_SWAP(hdrp->dsize); - M_32_SWAP(hdrp->ssize); - M_32_SWAP(hdrp->sshift); - M_32_SWAP(hdrp->ovfl_point); - M_32_SWAP(hdrp->last_freed); - M_32_SWAP(hdrp->max_bucket); - M_32_SWAP(hdrp->high_mask); - M_32_SWAP(hdrp->low_mask); - M_32_SWAP(hdrp->ffactor); - M_32_SWAP(hdrp->nkeys); - M_32_SWAP(hdrp->hdrpages); - M_32_SWAP(hdrp->h_charkey); - for (i = 0; i < NCACHED; i++) { - M_32_SWAP(hdrp->spares[i]); - M_16_SWAP(hdrp->bitmaps[i]); - } -} -#endif diff --git a/dbm/src/hash_buf.c b/dbm/src/hash_buf.c deleted file mode 100644 index 7bfe01a34..000000000 --- a/dbm/src/hash_buf.c +++ /dev/null @@ -1,408 +0,0 @@ -/*- - * 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 - * Margo Seltzer. - * - * 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[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -/* - * PACKAGE: hash - * - * DESCRIPTION: - * Contains buffer management - * - * ROUTINES: - * External - * __buf_init - * __get_buf - * __buf_free - * __reclaim_buf - * Internal - * newbuf - */ -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP) -#include <sys/param.h> -#endif - -#include <errno.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef DEBUG -#include <assert.h> -#endif - -#include "mcom_db.h" -#include "hash.h" -#include "page.h" -/* #include "extern.h" */ - -static BUFHEAD *newbuf __P((HTAB *, uint32, BUFHEAD *)); - -/* Unlink B from its place in the lru */ -#define BUF_REMOVE(B) { \ - (B)->prev->next = (B)->next; \ - (B)->next->prev = (B)->prev; \ -} - -/* Insert B after P */ -#define BUF_INSERT(B, P) { \ - (B)->next = (P)->next; \ - (B)->prev = (P); \ - (P)->next = (B); \ - (B)->next->prev = (B); \ -} - -#define MRU hashp->bufhead.next -#define LRU hashp->bufhead.prev - -#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead) -#define LRU_INSERT(B) BUF_INSERT((B), LRU) - -/* - * We are looking for a buffer with address "addr". If prev_bp is NULL, then - * address is a bucket index. If prev_bp is not NULL, then it points to the - * page previous to an overflow page that we are trying to find. - * - * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer - * be valid. Therefore, you must always verify that its address matches the - * address you are seeking. - */ -extern BUFHEAD * -__get_buf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp, int newpage) -/* If prev_bp set, indicates a new overflow page. */ -{ - register BUFHEAD *bp; - register uint32 is_disk_mask; - register int is_disk, segment_ndx = 0; - SEGMENT segp = 0; - - is_disk = 0; - is_disk_mask = 0; - if (prev_bp) { - bp = prev_bp->ovfl; - if (!bp || (bp->addr != addr)) - bp = NULL; - if (!newpage) - is_disk = BUF_DISK; - } else { - /* Grab buffer out of directory */ - segment_ndx = addr & (hashp->SGSIZE - 1); - - /* valid segment ensured by __call_hash() */ - segp = hashp->dir[addr >> hashp->SSHIFT]; -#ifdef DEBUG - assert(segp != NULL); -#endif - - bp = PTROF(segp[segment_ndx]); - - is_disk_mask = ISDISK(segp[segment_ndx]); - is_disk = is_disk_mask || !hashp->new_file; - } - - if (!bp) { - bp = newbuf(hashp, addr, prev_bp); - if (!bp) - return(NULL); - if(__get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0)) - { - /* free bp and its page */ - if(prev_bp) - { - /* if prev_bp is set then the new page that - * failed is hooked onto prev_bp as an overflow page. - * if we don't remove the pointer to the bad page - * we may try and access it later and we will die - * horribly because it will have already been - * free'd and overwritten with bogus data. - */ - prev_bp->ovfl = NULL; - } - BUF_REMOVE(bp); - free(bp->page); - free(bp); - return (NULL); - } - - if (!prev_bp) - { -#if 0 - /* 16 bit windows and mac can't handle the - * oring of the is disk flag. - */ - segp[segment_ndx] = - (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask); -#else - /* set the is_disk thing inside the structure - */ - bp->is_disk = is_disk_mask; - segp[segment_ndx] = bp; -#endif - } - } else { - BUF_REMOVE(bp); - MRU_INSERT(bp); - } - return (bp); -} - -/* - * We need a buffer for this page. Either allocate one, or evict a resident - * one (if we have as many buffers as we're allowed) and put this one in. - * - * If newbuf finds an error (returning NULL), it also sets errno. - */ -static BUFHEAD * -newbuf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp) -{ - register BUFHEAD *bp; /* The buffer we're going to use */ - register BUFHEAD *xbp; /* Temp pointer */ - register BUFHEAD *next_xbp; - SEGMENT segp; - int segment_ndx; - uint16 oaddr, *shortp; - - oaddr = 0; - bp = LRU; - /* - * If LRU buffer is pinned, the buffer pool is too small. We need to - * allocate more buffers. - */ - if (hashp->nbufs || (bp->flags & BUF_PIN)) { - /* Allocate a new one */ - if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL) - return (NULL); - - /* this memset is supposedly unnecessary but lets add - * it anyways. - */ - memset(bp, 0xff, sizeof(BUFHEAD)); - - if ((bp->page = (char *)malloc((size_t)hashp->BSIZE)) == NULL) { - free(bp); - return (NULL); - } - - /* this memset is supposedly unnecessary but lets add - * it anyways. - */ - memset(bp->page, 0xff, (size_t)hashp->BSIZE); - - if (hashp->nbufs) - hashp->nbufs--; - } else { - /* Kick someone out */ - BUF_REMOVE(bp); - /* - * If this is an overflow page with addr 0, it's already been - * flushed back in an overflow chain and initialized. - */ - if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) { - /* - * Set oaddr before __put_page so that you get it - * before bytes are swapped. - */ - shortp = (uint16 *)bp->page; - if (shortp[0]) - { - if(shortp[0] > (hashp->BSIZE / sizeof(uint16))) - { - return(NULL); - } - oaddr = shortp[shortp[0] - 1]; - } - if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page, - bp->addr, (int)IS_BUCKET(bp->flags), 0)) - return (NULL); - /* - * Update the pointer to this page (i.e. invalidate it). - * - * If this is a new file (i.e. we created it at open - * time), make sure that we mark pages which have been - * written to disk so we retrieve them from disk later, - * rather than allocating new pages. - */ - if (IS_BUCKET(bp->flags)) { - segment_ndx = bp->addr & (hashp->SGSIZE - 1); - segp = hashp->dir[bp->addr >> hashp->SSHIFT]; -#ifdef DEBUG - assert(segp != NULL); -#endif - - if (hashp->new_file && - ((bp->flags & BUF_MOD) || - ISDISK(segp[segment_ndx]))) - segp[segment_ndx] = (BUFHEAD *)BUF_DISK; - else - segp[segment_ndx] = NULL; - } - /* - * Since overflow pages can only be access by means of - * their bucket, free overflow pages associated with - * this bucket. - */ - for (xbp = bp; xbp->ovfl;) { - next_xbp = xbp->ovfl; - xbp->ovfl = 0; - xbp = next_xbp; - - /* Check that ovfl pointer is up date. */ - if (IS_BUCKET(xbp->flags) || - (oaddr != xbp->addr)) - break; - - shortp = (uint16 *)xbp->page; - if (shortp[0]) - { - /* LJM is the number of reported - * pages way too much? - */ - if(shortp[0] > hashp->BSIZE/sizeof(uint16)) - return NULL; - /* set before __put_page */ - oaddr = shortp[shortp[0] - 1]; - } - if ((xbp->flags & BUF_MOD) && __put_page(hashp, - xbp->page, xbp->addr, 0, 0)) - return (NULL); - xbp->addr = 0; - xbp->flags = 0; - BUF_REMOVE(xbp); - LRU_INSERT(xbp); - } - } - } - - /* Now assign this buffer */ - bp->addr = addr; -#ifdef DEBUG1 - (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n", - bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0); -#endif - bp->ovfl = NULL; - if (prev_bp) { - /* - * If prev_bp is set, this is an overflow page, hook it in to - * the buffer overflow links. - */ -#ifdef DEBUG1 - (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n", - prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0), - (bp ? bp->addr : 0)); -#endif - prev_bp->ovfl = bp; - bp->flags = 0; - } else - bp->flags = BUF_BUCKET; - MRU_INSERT(bp); - return (bp); -} - -extern void __buf_init(HTAB *hashp, int32 nbytes) -{ - BUFHEAD *bfp; - int npages; - - bfp = &(hashp->bufhead); - npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT; - npages = PR_MAX(npages, MIN_BUFFERS); - - hashp->nbufs = npages; - bfp->next = bfp; - bfp->prev = bfp; - /* - * This space is calloc'd so these are already null. - * - * bfp->ovfl = NULL; - * bfp->flags = 0; - * bfp->page = NULL; - * bfp->addr = 0; - */ -} - -extern int -__buf_free(HTAB *hashp, int do_free, int to_disk) -{ - BUFHEAD *bp; - int status = -1; - - /* Need to make sure that buffer manager has been initialized */ - if (!LRU) - return (0); - for (bp = LRU; bp != &hashp->bufhead;) { - /* Check that the buffer is valid */ - if (bp->addr || IS_BUCKET(bp->flags)) { - if (to_disk && (bp->flags & BUF_MOD) && - (status = __put_page(hashp, bp->page, - bp->addr, IS_BUCKET(bp->flags), 0))) { - - if (do_free) { - if (bp->page) - free(bp->page); - BUF_REMOVE(bp); - free(bp); - } - - return (status); - } - } - /* Check if we are freeing stuff */ - if (do_free) { - if (bp->page) - free(bp->page); - BUF_REMOVE(bp); - free(bp); - bp = LRU; - } else - bp = bp->prev; - } - return (0); -} - -extern void -__reclaim_buf(HTAB *hashp, BUFHEAD *bp) -{ - bp->ovfl = 0; - bp->addr = 0; - bp->flags = 0; - BUF_REMOVE(bp); - LRU_INSERT(bp); -} diff --git a/dbm/src/hsearch.c b/dbm/src/hsearch.c deleted file mode 100644 index fb8a58bad..000000000 --- a/dbm/src/hsearch.c +++ /dev/null @@ -1,108 +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 - * Margo Seltzer. - * - * 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[] = "@(#)hsearch.c 8.4 (Berkeley) 7/21/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#ifndef macintosh -#include <sys/types.h> -#endif - -#include <fcntl.h> -#include <string.h> - -#include "mcom_db.h" -#include "hsearch.h" - -static DB *dbp = NULL; -static ENTRY retval; - -extern int -hcreate(uint nel) -{ - HASHINFO info; - - info.nelem = nel; - info.bsize = 256; - info.ffactor = 8; - info.cachesize = 0; - info.hash = NULL; - info.lorder = 0; - dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0); - return ((int)dbp); -} - -extern ENTRY * -hsearch(ENTRY item, ACTION action) -{ - DBT key, val; - int status; - - if (!dbp) - return (NULL); - key.data = (uint8 *)item.key; - key.size = strlen(item.key) + 1; - - if (action == ENTER) { - val.data = (uint8 *)item.data; - val.size = strlen(item.data) + 1; - status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE); - if (status) - return (NULL); - } else { - /* FIND */ - status = (dbp->get)(dbp, &key, &val, 0); - if (status) - return (NULL); - else - item.data = (char *)val.data; - } - retval.key = item.key; - retval.data = item.data; - return (&retval); -} - -extern void -hdestroy() -{ - if (dbp) { - (void)(dbp->close)(dbp); - dbp = NULL; - } -} diff --git a/dbm/src/memmove.c b/dbm/src/memmove.c deleted file mode 100644 index c4f9ff02e..000000000 --- a/dbm/src/memmove.c +++ /dev/null @@ -1,150 +0,0 @@ -#if defined(__sun) && !defined(__svr4__) -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * 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[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#else -#include "cdefs.h" -#endif -#include <string.h> - -/* - * sizeof(word) MUST BE A POWER OF TWO - * SO THAT wmask BELOW IS ALL ONES - */ -typedef int word; /* "word" used for optimal copy speed */ - -#define wsize sizeof(word) -#define wmask (wsize - 1) - -/* - * Copy a block of memory, handling overlap. - * This is the routine that actually implements - * (the portable versions of) bcopy, memcpy, and memmove. - */ -#ifdef MEMCOPY -void * -memcpy(dst0, src0, length) -#else -#ifdef MEMMOVE -void * -memmove(dst0, src0, length) -#else -void -bcopy(src0, dst0, length) -#endif -#endif - void *dst0; - const void *src0; - register size_t length; -{ - register char *dst = dst0; - register const char *src = src0; - register size_t t; - - if (length == 0 || dst == src) /* nothing to do */ - goto done; - - /* - * Macros: loop-t-times; and loop-t-times, t>0 - */ -#define TLOOP(s) if (t) TLOOP1(s) -#define TLOOP1(s) do { s; } while (--t) - - if ((unsigned long)dst < (unsigned long)src) { - /* - * Copy forward. - */ - t = (int)src; /* only need low bits */ - if ((t | (int)dst) & wmask) { - /* - * Try to align operands. This cannot be done - * unless the low bits match. - */ - if ((t ^ (int)dst) & wmask || length < wsize) - t = length; - else - t = wsize - (t & wmask); - length -= t; - TLOOP1(*dst++ = *src++); - } - /* - * Copy whole words, then mop up any trailing bytes. - */ - t = length / wsize; - TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); - t = length & wmask; - TLOOP(*dst++ = *src++); - } else { - /* - * Copy backwards. Otherwise essentially the same. - * Alignment works as before, except that it takes - * (t&wmask) bytes to align, not wsize-(t&wmask). - */ - src += length; - dst += length; - t = (int)src; - if ((t | (int)dst) & wmask) { - if ((t ^ (int)dst) & wmask || length <= wsize) - t = length; - else - t &= wmask; - length -= t; - TLOOP1(*--dst = *--src); - } - t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); - t = length & wmask; - TLOOP(*--dst = *--src); - } -done: -#if defined(MEMCOPY) || defined(MEMMOVE) - return (dst0); -#else - return; -#endif -} -#endif /* no __sgi */ - -/* Some compilers don't like an empty source file. */ -static int dummy = 0; diff --git a/dbm/src/mktemp.c b/dbm/src/mktemp.c deleted file mode 100644 index 574eb9fe5..000000000 --- a/dbm/src/mktemp.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#ifdef macintosh -#include <unix.h> -#else -#include <sys/types.h> -#include <sys/stat.h> -#endif -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <ctype.h> -#include "mcom_db.h" - -#if !defined(_WINDOWS) && !defined(XP_OS2_VACPP) -#include <unistd.h> -#endif - -#ifdef XP_OS2_VACPP -#define ENOTDIR EBADPOS -#include <process.h> -#include <dirent.h> -#endif - -#ifdef _WINDOWS -#include <process.h> -#include "winfile.h" -#endif - -static int _gettemp(char *path, register int *doopen, int extraFlags); - -int -mkstemp(char *path) -{ -#ifdef XP_OS2 - FILE *temp = tmpfile(); - - return (temp ? fileno(temp) : -1); -#else - int fd; - - return (_gettemp(path, &fd, 0) ? fd : -1); -#endif -} - -int -mkstempflags(char *path, int extraFlags) -{ - int fd; - - return (_gettemp(path, &fd, extraFlags) ? fd : -1); -} - -char * -mktemp(char *path) -{ - return(_gettemp(path, (int *)NULL, 0) ? path : (char *)NULL); -} - -/* NB: This routine modifies its input string, and does not always restore it. -** returns 1 on success, 0 on failure. -*/ -static int -_gettemp(char *path, register int *doopen, int extraFlags) -{ -#if !defined(_WINDOWS) || defined(_WIN32) - extern int errno; -#endif - register char *start, *trv; - struct stat sbuf; - unsigned int pid; - - pid = getpid(); - for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ - while (*--trv == 'X') { - *trv = (pid % 10) + '0'; - pid /= 10; - } - - /* - * check the target directory; if you have six X's and it - * doesn't exist this runs for a *very* long time. - */ - for (start = trv + 1;; --trv) { - char saved; - if (trv <= path) - break; - saved = *trv; - if (saved == '/' || saved == '\\') { - int rv; - *trv = '\0'; - rv = stat(path, &sbuf); - *trv = saved; - if (rv) - return(0); - if (!S_ISDIR(sbuf.st_mode)) { - errno = ENOTDIR; - return(0); - } - break; - } - } - - for (;;) { - if (doopen) { - if ((*doopen = - open(path, O_CREAT|O_EXCL|O_RDWR|extraFlags, 0600)) >= 0) - return(1); - if (errno != EEXIST) - return(0); - } - else if (stat(path, &sbuf)) - return(errno == ENOENT ? 1 : 0); - - /* tricky little algorithm for backward compatibility */ - for (trv = start;;) { - if (!*trv) - return(0); - if (*trv == 'z') - *trv++ = 'a'; - else { - if (isdigit(*trv)) - *trv = 'a'; - else - ++*trv; - break; - } - } - } - /*NOTREACHED*/ -} diff --git a/dbm/src/ndbm.c b/dbm/src/ndbm.c deleted file mode 100644 index ca008de0c..000000000 --- a/dbm/src/ndbm.c +++ /dev/null @@ -1,195 +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 - * Margo Seltzer. - * - * 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[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -/* - * This package provides a dbm compatible interface to the new hashing - * package described in db(3). - */ -#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(XP_OS2_VACPP) -#include <sys/param.h> -#endif - -#if defined(__linux) -#include <linux/limits.h> -#endif - -#include <stdio.h> -#include <string.h> - -#include "ndbm.h" -#include "hash.h" - -/* - * Returns: - * *DBM on success - * NULL on failure - */ -extern DBM * -dbm_open(const char *file, int flags, int mode) -{ - HASHINFO info; - char path[MAXPATHLEN]; - - info.bsize = 4096; - info.ffactor = 40; - info.nelem = 1; - info.cachesize = 0; - info.hash = NULL; - info.lorder = 0; - (void)strcpy(path, file); - (void)strcat(path, DBM_SUFFIX); - return ((DBM *)__hash_open(path, flags, mode, &info, 0)); -} - -extern void -dbm_close(DBM *db) -{ - (void)(db->close)(db); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -extern datum -dbm_fetch(DBM *db, datum key) -{ - datum retval; - int status; - - status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0); - if (status) { - retval.dptr = NULL; - retval.dsize = 0; - } - return (retval); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -extern datum -dbm_firstkey(DBM *db) -{ - int status; - datum retdata, retkey; - - status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST); - if (status) - retkey.dptr = NULL; - return (retkey); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -extern datum -dbm_nextkey(DBM *db) -{ - int status; - datum retdata, retkey; - - status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT); - if (status) - retkey.dptr = NULL; - return (retkey); -} -/* - * Returns: - * 0 on success - * <0 failure - */ -extern int -dbm_delete(DBM *db, datum key) -{ - int status; - - status = (db->del)(db, (DBT *)&key, 0); - if (status) - return (-1); - else - return (0); -} - -/* - * Returns: - * 0 on success - * <0 failure - * 1 if DBM_INSERT and entry exists - */ -extern int -dbm_store(DBM *db, datum key, datum content, int flags) -{ - return ((db->put)(db, (DBT *)&key, (DBT *)&content, - (flags == DBM_INSERT) ? R_NOOVERWRITE : 0)); -} - - -extern int -dbm_error(DBM *db) -{ - HTAB *hp; - - hp = (HTAB *)db->internal; - return (hp->dbmerrno); -} - -extern int -dbm_clearerr(DBM *db) -{ - HTAB *hp; - - hp = (HTAB *)db->internal; - hp->dbmerrno = 0; - return (0); -} - -extern int -dbm_dirfno(DBM *db) -{ - return(((HTAB *)db->internal)->fp); -} diff --git a/dbm/src/nsres.c b/dbm/src/nsres.c deleted file mode 100644 index 44b448cf7..000000000 --- a/dbm/src/nsres.c +++ /dev/null @@ -1,311 +0,0 @@ -#include "watcomfx.h" - -#include "nsres.h" - -#include <stdio.h> - -#if defined(BSDI)||defined(RHAPSODY) -#include <stdlib.h> -#else -#include <malloc.h> -#endif - -#include <string.h> - -struct RESDATABASE -{ - DB *hdb; - NSRESTHREADINFO *threadinfo; - char * pbuf[MAXBUFNUM]; -} ; -typedef struct RESDATABASE * RESHANDLE; - -typedef struct STRINGDATA -{ - char *str; - unsigned int charsetid; -} STRINGDATA; - - -typedef unsigned int CHARSETTYPE; -#define RES_LOCK if (hres->threadinfo) hres->threadinfo->fn_lock(hres->threadinfo->lock); -#define RES_UNLOCK if (hres->threadinfo) hres->threadinfo->fn_unlock(hres->threadinfo->lock); - -int GenKeyData(const char *library, int32 id, DBT *key); - -/* - Right now, the page size used for resource is same as for Navigator cache - database - */ -HASHINFO res_hash_info = { - 32*1024, - 0, - 0, - 0, - 0, /* 64 * 1024U */ - 0}; - -int GenKeyData(const char *library, int32 id, DBT *key) -{ - char idstr[10]; - static char * strdata = NULL; - size_t len; - - if (strdata) - free (strdata); - - if (id == 0) - idstr[0] = '\0'; - else - { - sprintf(idstr, "%d", id); - /* itoa(id, idstr, 10); */ - } - - if (library == NULL) - len = strlen(idstr) + 1; - else - len = strlen(library) + strlen(idstr) + 1; - strdata = (char *) malloc (len); - strcpy(strdata, library); - strcat(strdata, idstr); - - key->size = len; - key->data = strdata; - - return 1; -} - -NSRESHANDLE NSResCreateTable(const char *filename, NSRESTHREADINFO *threadinfo) -{ - RESHANDLE hres; - int flag; - - flag = O_RDWR | O_CREAT; - - hres = (RESHANDLE) malloc ( sizeof(struct RESDATABASE) ); - memset(hres, 0, sizeof(struct RESDATABASE)); - - if (threadinfo && threadinfo->lock && threadinfo->fn_lock - && threadinfo->fn_unlock) - { - hres->threadinfo = (NSRESTHREADINFO *) malloc( sizeof(NSRESTHREADINFO) ); - hres->threadinfo->lock = threadinfo->lock; - hres->threadinfo->fn_lock = threadinfo->fn_lock; - hres->threadinfo->fn_unlock = threadinfo->fn_unlock; - } - - - RES_LOCK - - hres->hdb = dbopen(filename, flag, 0644, DB_HASH, &res_hash_info); - - RES_UNLOCK - - if(!hres->hdb) - return NULL; - - return (NSRESHANDLE) hres; -} - -NSRESHANDLE NSResOpenTable(const char *filename, NSRESTHREADINFO *threadinfo) -{ - RESHANDLE hres; - int flag; - - flag = O_RDONLY; /* only open database for reading */ - - hres = (RESHANDLE) malloc ( sizeof(struct RESDATABASE) ); - memset(hres, 0, sizeof(struct RESDATABASE)); - - if (threadinfo && threadinfo->lock && threadinfo->fn_lock - && threadinfo->fn_unlock) - { - hres->threadinfo = (NSRESTHREADINFO *) malloc( sizeof(NSRESTHREADINFO) ); - hres->threadinfo->lock = threadinfo->lock; - hres->threadinfo->fn_lock = threadinfo->fn_lock; - hres->threadinfo->fn_unlock = threadinfo->fn_unlock; - } - - - RES_LOCK - - hres->hdb = dbopen(filename, flag, 0644, DB_HASH, &res_hash_info); - - RES_UNLOCK - - if(!hres->hdb) - return NULL; - - return (NSRESHANDLE) hres; -} - - - -void NSResCloseTable(NSRESHANDLE handle) -{ - RESHANDLE hres; - int i; - - if (handle == NULL) - return; - hres = (RESHANDLE) handle; - - RES_LOCK - - (*hres->hdb->sync)(hres->hdb, 0); - (*hres->hdb->close)(hres->hdb); - - RES_UNLOCK - - for (i = 0; i < MAXBUFNUM; i++) - { - if (hres->pbuf[i]) - free (hres->pbuf[i]); - } - - if (hres->threadinfo) - free (hres->threadinfo); - free (hres); -} - - -char *NSResLoadString(NSRESHANDLE handle, const char * library, int32 id, - unsigned int charsetid, char *retbuf) -{ - int status; - RESHANDLE hres; - DBT key, data; - if (handle == NULL) - return NULL; - - hres = (RESHANDLE) handle; - GenKeyData(library, id, &key); - - RES_LOCK - - status = (*hres->hdb->get)(hres->hdb, &key, &data, 0); - - RES_UNLOCK - - if (retbuf) - { - memcpy(retbuf, (char *)data.data + sizeof(CHARSETTYPE), data.size - sizeof(CHARSETTYPE)); - return retbuf; - } - else - { - static int WhichString = 0; - static int bFirstTime = 1; - char *szLoadedString; - int i; - - RES_LOCK - - if (bFirstTime) { - for (i = 0; i < MAXBUFNUM; i++) - hres->pbuf[i] = (char *) malloc(MAXSTRINGLEN * sizeof(char)); - bFirstTime = 0; - } - - szLoadedString = hres->pbuf[WhichString]; - WhichString++; - - /* reset to 0, if WhichString reaches to the end */ - if (WhichString == MAXBUFNUM) - WhichString = 0; - - if (status == 0) - memcpy(szLoadedString, (char *) data.data + sizeof(CHARSETTYPE), - data.size - sizeof(CHARSETTYPE)); - else - szLoadedString[0] = 0; - - RES_UNLOCK - - return szLoadedString; - } -} - -int32 NSResGetSize(NSRESHANDLE handle, const char *library, int32 id) -{ - int status; - RESHANDLE hres; - DBT key, data; - if (handle == NULL) - return 0; - hres = (RESHANDLE) handle; - GenKeyData(library, id, &key); - - RES_LOCK - - status = (*hres->hdb->get)(hres->hdb, &key, &data, 0); - - RES_UNLOCK - - return data.size - sizeof(CHARSETTYPE); -} - -int32 NSResLoadResource(NSRESHANDLE handle, const char *library, int32 id, char *retbuf) -{ - int status; - RESHANDLE hres; - DBT key, data; - if (handle == NULL) - return 0; - hres = (RESHANDLE) handle; - GenKeyData(library, id, &key); - - RES_LOCK - - status = (*hres->hdb->get)(hres->hdb, &key, &data, 0); - - RES_UNLOCK - - if (retbuf) - { - memcpy(retbuf, (char *)data.data + sizeof(CHARSETTYPE), data.size - sizeof(CHARSETTYPE)); - return data.size; - } - else - return 0; -} - -int NSResAddString(NSRESHANDLE handle, const char *library, int32 id, - const char *string, unsigned int charset) -{ - int status; - RESHANDLE hres; - DBT key, data; - char * recdata; - - if (handle == NULL) - return 0; - hres = (RESHANDLE) handle; - - GenKeyData(library, id, &key); - - data.size = sizeof(CHARSETTYPE) + (strlen(string) + 1) ; - - recdata = (char *) malloc(data.size) ; - - /* set charset to the first field of record data */ - *((CHARSETTYPE *)recdata) = (CHARSETTYPE)charset; - - /* set data field */ - memcpy(recdata+sizeof(CHARSETTYPE), string, strlen(string) + 1); - - data.data = recdata; - - RES_LOCK - - status = (*hres->hdb->put)(hres->hdb, &key, &data, 0); - - - if (recdata) - free(recdata); - - RES_UNLOCK - - return status; -} diff --git a/dbm/src/snprintf.c b/dbm/src/snprintf.c deleted file mode 100644 index 7a6b2005c..000000000 --- a/dbm/src/snprintf.c +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef HAVE_SNPRINTF - -#include "watcomfx.h" -#include <sys/types.h> -#include <stddef.h> -#include <stdio.h> - -#if defined(_WINDOWS) || defined(SOLARIS) || defined(AIXV3) || defined(AIX) || defined(OSF1) || defined(NEC) || !defined(HAVE_SYS_CDEFS_H) -#include "cdefs.h" -#elif !defined(HPUX) && !defined(UNIXWARE) && !defined(SNI) -#include <sys/cdefs.h> -#endif - -#include "prtypes.h" - -#include <ncompat.h> - -/* The OS/2 VAC compiler doesn't appear to define __STDC__ and won't let us define it either */ -#if defined(__STDC__) || defined(XP_OS2_VACPP) -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -int -#if defined(__STDC__) || defined(XP_OS2_VACPP) -snprintf(char *str, size_t n, const char *fmt, ...) -#else -snprintf(str, n, fmt, va_alist) - char *str; - size_t n; - const char *fmt; - va_dcl -#endif -{ - va_list ap; -#ifdef VSPRINTF_CHARSTAR - char *rp; -#else - int rval; -#endif -#if defined(__STDC__) || defined(XP_OS2_VACPP) - va_start(ap, fmt); -#else - va_start(ap); -#endif -#ifdef VSPRINTF_CHARSTAR - rp = vsprintf(str, fmt, ap); - va_end(ap); - return (strlen(rp)); -#else - rval = vsprintf(str, fmt, ap); - va_end(ap); - return (rval); -#endif -} - -int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - va_list ap; -{ -#ifdef VSPRINTF_CHARSTAR - return (strlen(vsprintf(str, fmt, ap))); -#else - return (vsprintf(str, fmt, ap)); -#endif -} - -#endif /* HAVE_SNPRINTF */ - -/* Some compilers don't like an empty source file. */ -static int dummy = 0; diff --git a/dbm/src/strerror.c b/dbm/src/strerror.c deleted file mode 100644 index d1ae2666a..000000000 --- a/dbm/src/strerror.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * 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[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include "watcomfx.h" - -#include <string.h> - -#ifdef _DLL -#define sys_nerr (*_sys_nerr_dll) -#endif - -#ifndef HAVE_STRERROR -#ifndef _AFXDLL -char * -strerror(num) - int num; -{ - extern int sys_nerr; - extern char *sys_errlist[]; -#define UPREFIX "Unknown error: " - static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ - register unsigned int errnum; - register char *p, *t; - char tmp[40]; - - errnum = num; /* convert to unsigned */ - if (errnum < sys_nerr) - return(sys_errlist[errnum]); - - /* Do this by hand, so we don't include stdio(3). */ - t = tmp; - do { - *t++ = "0123456789"[errnum % 10]; - } while (errnum /= 10); - for (p = ebuf + sizeof(UPREFIX) - 1;;) { - *p++ = *--t; - if (t <= tmp) - break; - } - return(ebuf); -} - -#endif -#endif /* !HAVE_STRERROR */ |