xref: /freebsd/sys/kern/subr_hash.c (revision 02abd40029ea0d6cbb65cbb70816266541fb45a2)
128993443SEd Schouten /*-
228993443SEd Schouten  * Copyright (c) 1982, 1986, 1991, 1993
328993443SEd Schouten  *	The Regents of the University of California.  All rights reserved.
428993443SEd Schouten  * (c) UNIX System Laboratories, Inc.
528993443SEd Schouten  * All or some portions of this file are derived from material licensed
628993443SEd Schouten  * to the University of California by American Telephone and Telegraph
728993443SEd Schouten  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
828993443SEd Schouten  * the permission of UNIX System Laboratories, Inc.
928993443SEd Schouten  *
1028993443SEd Schouten  * Redistribution and use in source and binary forms, with or without
1128993443SEd Schouten  * modification, are permitted provided that the following conditions
1228993443SEd Schouten  * are met:
1328993443SEd Schouten  * 1. Redistributions of source code must retain the above copyright
1428993443SEd Schouten  *    notice, this list of conditions and the following disclaimer.
1528993443SEd Schouten  * 2. Redistributions in binary form must reproduce the above copyright
1628993443SEd Schouten  *    notice, this list of conditions and the following disclaimer in the
1728993443SEd Schouten  *    documentation and/or other materials provided with the distribution.
1828993443SEd Schouten  * 4. Neither the name of the University nor the names of its contributors
1928993443SEd Schouten  *    may be used to endorse or promote products derived from this software
2028993443SEd Schouten  *    without specific prior written permission.
2128993443SEd Schouten  *
2228993443SEd Schouten  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2328993443SEd Schouten  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2428993443SEd Schouten  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2528993443SEd Schouten  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2628993443SEd Schouten  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2728993443SEd Schouten  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2828993443SEd Schouten  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2928993443SEd Schouten  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3028993443SEd Schouten  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3128993443SEd Schouten  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3228993443SEd Schouten  * SUCH DAMAGE.
3328993443SEd Schouten  *
3428993443SEd Schouten  *	@(#)kern_subr.c	8.3 (Berkeley) 1/21/94
3528993443SEd Schouten  */
3628993443SEd Schouten 
3728993443SEd Schouten #include <sys/cdefs.h>
3828993443SEd Schouten __FBSDID("$FreeBSD$");
3928993443SEd Schouten 
4028993443SEd Schouten #include <sys/param.h>
4128993443SEd Schouten #include <sys/systm.h>
4228993443SEd Schouten #include <sys/malloc.h>
4328993443SEd Schouten 
4428993443SEd Schouten /*
4528993443SEd Schouten  * General routine to allocate a hash table with control of memory flags.
4628993443SEd Schouten  */
4728993443SEd Schouten void *
4828993443SEd Schouten hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask,
4928993443SEd Schouten     int flags)
5028993443SEd Schouten {
5128993443SEd Schouten 	long hashsize;
5228993443SEd Schouten 	LIST_HEAD(generic, generic) *hashtbl;
5328993443SEd Schouten 	int i;
5428993443SEd Schouten 
5593a1b4c4SGleb Smirnoff 	KASSERT(elements > 0, ("%s: bad elements", __func__));
5628993443SEd Schouten 	/* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */
5728993443SEd Schouten 	KASSERT((flags & HASH_WAITOK) ^ (flags & HASH_NOWAIT),
5828993443SEd Schouten 	    ("Bad flags (0x%x) passed to hashinit_flags", flags));
5928993443SEd Schouten 
6028993443SEd Schouten 	for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
6128993443SEd Schouten 		continue;
6228993443SEd Schouten 	hashsize >>= 1;
6328993443SEd Schouten 
6428993443SEd Schouten 	if (flags & HASH_NOWAIT)
6528993443SEd Schouten 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl),
6628993443SEd Schouten 		    type, M_NOWAIT);
6728993443SEd Schouten 	else
6828993443SEd Schouten 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl),
6928993443SEd Schouten 		    type, M_WAITOK);
7028993443SEd Schouten 
7128993443SEd Schouten 	if (hashtbl != NULL) {
7228993443SEd Schouten 		for (i = 0; i < hashsize; i++)
7328993443SEd Schouten 			LIST_INIT(&hashtbl[i]);
7428993443SEd Schouten 		*hashmask = hashsize - 1;
7528993443SEd Schouten 	}
7628993443SEd Schouten 	return (hashtbl);
7728993443SEd Schouten }
7828993443SEd Schouten 
7928993443SEd Schouten /*
8028993443SEd Schouten  * Allocate and initialize a hash table with default flag: may sleep.
8128993443SEd Schouten  */
8228993443SEd Schouten void *
8328993443SEd Schouten hashinit(int elements, struct malloc_type *type, u_long *hashmask)
8428993443SEd Schouten {
8528993443SEd Schouten 
8628993443SEd Schouten 	return (hashinit_flags(elements, type, hashmask, HASH_WAITOK));
8728993443SEd Schouten }
8828993443SEd Schouten 
8928993443SEd Schouten void
9028993443SEd Schouten hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
9128993443SEd Schouten {
9228993443SEd Schouten 	LIST_HEAD(generic, generic) *hashtbl, *hp;
9328993443SEd Schouten 
9428993443SEd Schouten 	hashtbl = vhashtbl;
9528993443SEd Schouten 	for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
96029f99dcSBjoern A. Zeeb 		KASSERT(LIST_EMPTY(hp), ("%s: hashtbl %p not empty "
97029f99dcSBjoern A. Zeeb 		    "(malloc type %s)", __func__, hashtbl, type->ks_shortdesc));
9828993443SEd Schouten 	free(hashtbl, type);
9928993443SEd Schouten }
10028993443SEd Schouten 
10128993443SEd Schouten static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531,
10228993443SEd Schouten 			2039, 2557, 3067, 3583, 4093, 4603, 5119, 5623, 6143,
10328993443SEd Schouten 			6653, 7159, 7673, 8191, 12281, 16381, 24571, 32749 };
104*02abd400SPedro F. Giffuni #define	NPRIMES nitems(primes)
10528993443SEd Schouten 
10628993443SEd Schouten /*
10728993443SEd Schouten  * General routine to allocate a prime number sized hash table.
10828993443SEd Schouten  */
10928993443SEd Schouten void *
11028993443SEd Schouten phashinit(int elements, struct malloc_type *type, u_long *nentries)
11128993443SEd Schouten {
11228993443SEd Schouten 	long hashsize;
11328993443SEd Schouten 	LIST_HEAD(generic, generic) *hashtbl;
11428993443SEd Schouten 	int i;
11528993443SEd Schouten 
11693a1b4c4SGleb Smirnoff 	KASSERT(elements > 0, ("%s: bad elements", __func__));
11728993443SEd Schouten 	for (i = 1, hashsize = primes[1]; hashsize <= elements;) {
11828993443SEd Schouten 		i++;
11928993443SEd Schouten 		if (i == NPRIMES)
12028993443SEd Schouten 			break;
12128993443SEd Schouten 		hashsize = primes[i];
12228993443SEd Schouten 	}
12328993443SEd Schouten 	hashsize = primes[i - 1];
12428993443SEd Schouten 	hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
12528993443SEd Schouten 	for (i = 0; i < hashsize; i++)
12628993443SEd Schouten 		LIST_INIT(&hashtbl[i]);
12728993443SEd Schouten 	*nentries = hashsize;
12828993443SEd Schouten 	return (hashtbl);
12928993443SEd Schouten }
130