BSD 4_4 release
[unix-history] / usr / src / lib / libc / db / hash / hash.c
index cb8fe94..8344fae 100644 (file)
@@ -1,15 +1,41 @@
 /*-
 /*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * 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.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * Margo Seltzer.
  *
- * %sccs.include.redist.c%
+ * 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)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c     5.31 (Berkeley) %G%";
+static char sccsid[] = "@(#)hash.c     8.1 (Berkeley) 7/19/93";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
@@ -35,16 +61,17 @@ static int   flush_meta __P((HTAB *));
 static int   hash_access __P((HTAB *, ACTION, DBT *, DBT *));
 static int   hash_close __P((DB *));
 static int   hash_delete __P((const DB *, const DBT *, u_int));
 static int   hash_access __P((HTAB *, ACTION, DBT *, DBT *));
 static int   hash_close __P((DB *));
 static int   hash_delete __P((const DB *, const DBT *, u_int));
+static int   hash_fd __P((const DB *));
 static int   hash_get __P((const DB *, const DBT *, DBT *, u_int));
 static int   hash_put __P((const DB *, DBT *, const DBT *, u_int));
 static void *hash_realloc __P((SEGMENT **, int, int));
 static int   hash_seq __P((const DB *, DBT *, DBT *, u_int));
 static int   hash_get __P((const DB *, const DBT *, DBT *, u_int));
 static int   hash_put __P((const DB *, DBT *, const DBT *, u_int));
 static void *hash_realloc __P((SEGMENT **, int, int));
 static int   hash_seq __P((const DB *, DBT *, DBT *, u_int));
-static int   hash_sync __P((const DB *));
+static int   hash_sync __P((const DB *, u_int));
 static int   hdestroy __P((HTAB *));
 static int   hdestroy __P((HTAB *));
-static HTAB *init_hash __P((HTAB *, HASHINFO *));
+static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *));
 static int   init_htab __P((HTAB *, int));
 #if BYTE_ORDER == LITTLE_ENDIAN
 static int   init_htab __P((HTAB *, int));
 #if BYTE_ORDER == LITTLE_ENDIAN
-static void  swap_header __P((HTAB *, void));
+static void  swap_header __P((HTAB *));
 static void  swap_header_copy __P((HASHHDR *, HASHHDR *));
 #endif
 
 static void  swap_header_copy __P((HASHHDR *, HASHHDR *));
 #endif
 
@@ -105,7 +132,7 @@ __hash_open(file, flags, mode, info)
                (void)fcntl(hashp->fp, F_SETFD, 1);
        }
        if (new_table) {
                (void)fcntl(hashp->fp, F_SETFD, 1);
        }
        if (new_table) {
-               if (!(hashp = init_hash(hashp, (HASHINFO *)info)))
+               if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
                        RETURN_ERROR(errno, error1);
        } else {
                /* Table already exists */
                        RETURN_ERROR(errno, error1);
        } else {
                /* Table already exists */
@@ -170,6 +197,7 @@ __hash_open(file, flags, mode, info)
        dbp->internal = hashp;
        dbp->close = hash_close;
        dbp->del = hash_delete;
        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->get = hash_get;
        dbp->put = hash_put;
        dbp->seq = hash_seq;
@@ -226,12 +254,31 @@ hash_close(dbp)
        return (retval);
 }
 
        return (retval);
 }
 
+static int
+hash_fd(dbp)
+       const DB *dbp;
+{
+       HTAB *hashp;
+
+       if (!dbp)
+               return (ERROR);
+
+       hashp = (HTAB *)dbp->internal;
+       if (hashp->fp == -1) {
+               errno = ENOENT;
+               return (-1);
+       }
+       return (hashp->fp);
+}
+
 /************************** LOCAL CREATION ROUTINES **********************/
 static HTAB *
 /************************** LOCAL CREATION ROUTINES **********************/
 static HTAB *
-init_hash(hashp, info)
+init_hash(hashp, file, info)
        HTAB *hashp;
        HTAB *hashp;
+       const char *file;
        HASHINFO *info;
 {
        HASHINFO *info;
 {
+       struct stat statbuf;
        int nelem;
 
        nelem = 1;
        int nelem;
 
        nelem = 1;
@@ -244,8 +291,16 @@ init_hash(hashp, info)
        hashp->DSIZE = DEF_DIRSIZE;
        hashp->FFACTOR = DEF_FFACTOR;
        hashp->hash = __default_hash;
        hashp->DSIZE = DEF_DIRSIZE;
        hashp->FFACTOR = DEF_FFACTOR;
        hashp->hash = __default_hash;
-       bzero(hashp->SPARES, sizeof(hashp->SPARES));
-       bzero (hashp->BITMAPS, sizeof (hashp->BITMAPS));
+       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);
+               hashp->BSIZE = statbuf.st_blksize;
+               hashp->BSHIFT = __log2(hashp->BSIZE);
+       }
 
        if (info) {
                if (info->bsize) {
 
        if (info) {
                if (info->bsize) {
@@ -389,11 +444,17 @@ hdestroy(hashp)
  *     -1 ERROR
  */
 static int
  *     -1 ERROR
  */
 static int
-hash_sync(dbp)
+hash_sync(dbp, flags)
        const DB *dbp;
        const DB *dbp;
+       u_int flags;
 {
        HTAB *hashp;
 
 {
        HTAB *hashp;
 
+       if (flags != 0) {
+               errno = EINVAL;
+               return (ERROR);
+       }
+
        if (!dbp)
                return (ERROR);
 
        if (!dbp)
                return (ERROR);
 
@@ -552,7 +613,7 @@ hash_access(hashp, action, key, val)
                if (bp[1] >= REAL_KEY) {
                        /* Real key/data pair */
                        if (size == off - *bp &&
                if (bp[1] >= REAL_KEY) {
                        /* Real key/data pair */
                        if (size == off - *bp &&
-                           bcmp(kp, rbufp->page + *bp, size) == 0)
+                           memcmp(kp, rbufp->page + *bp, size) == 0)
                                goto found;
                        off = bp[1];
 #ifdef HASH_STATISTICS
                                goto found;
                        off = bp[1];
 #ifdef HASH_STATISTICS
@@ -803,8 +864,8 @@ hash_realloc(p_ptr, oldsize, newsize)
        register void *p;
 
        if (p = malloc(newsize)) {
        register void *p;
 
        if (p = malloc(newsize)) {
-               bcopy(*p_ptr, p, oldsize);
-               bzero(*p_ptr + oldsize, newsize - oldsize);
+               memmove(p, *p_ptr, oldsize);
+               memset((char *)p + oldsize, 0, newsize - oldsize);
                free(*p_ptr);
                *p_ptr = p;
        }
                free(*p_ptr);
                *p_ptr = p;
        }