xref: /f-stack/freebsd/sys/hash.h (revision 22ce4aff)
1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*22ce4affSfengbojiang  *
4a9643ea8Slogwang  * Copyright (c) 2001 Tobias Weingartner
5a9643ea8Slogwang  * All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
8a9643ea8Slogwang  * modification, are permitted provided that the following conditions
9a9643ea8Slogwang  * are met:
10a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
11a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
12a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
13a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
14a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
15a9643ea8Slogwang  *
16a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17a9643ea8Slogwang  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18a9643ea8Slogwang  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19a9643ea8Slogwang  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20a9643ea8Slogwang  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21a9643ea8Slogwang  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22a9643ea8Slogwang  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23a9643ea8Slogwang  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24a9643ea8Slogwang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25a9643ea8Slogwang  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26a9643ea8Slogwang  *
27a9643ea8Slogwang  * $OpenBSD: hash.h,v 1.4 2004/05/25 18:37:23 jmc Exp $
28a9643ea8Slogwang  * $FreeBSD$
29a9643ea8Slogwang  */
30a9643ea8Slogwang 
31a9643ea8Slogwang #ifndef _SYS_HASH_H_
32a9643ea8Slogwang #define	_SYS_HASH_H_
33a9643ea8Slogwang #include <sys/types.h>
34a9643ea8Slogwang 
35a9643ea8Slogwang /* Convenience */
36a9643ea8Slogwang #ifndef	HASHINIT
37a9643ea8Slogwang #define	HASHINIT	5381
38a9643ea8Slogwang #define	HASHSTEP(x,c)	(((x << 5) + x) + (c))
39a9643ea8Slogwang #endif
40a9643ea8Slogwang 
41a9643ea8Slogwang /*
42a9643ea8Slogwang  * Return a 32-bit hash of the given buffer.  The init
43a9643ea8Slogwang  * value should be 0, or the previous hash value to extend
44a9643ea8Slogwang  * the previous hash.
45a9643ea8Slogwang  */
46a9643ea8Slogwang static __inline uint32_t
hash32_buf(const void * buf,size_t len,uint32_t hash)47a9643ea8Slogwang hash32_buf(const void *buf, size_t len, uint32_t hash)
48a9643ea8Slogwang {
49a9643ea8Slogwang 	const unsigned char *p = buf;
50a9643ea8Slogwang 
51a9643ea8Slogwang 	while (len--)
52a9643ea8Slogwang 		hash = HASHSTEP(hash, *p++);
53a9643ea8Slogwang 
54a9643ea8Slogwang 	return hash;
55a9643ea8Slogwang }
56a9643ea8Slogwang 
57a9643ea8Slogwang /*
58a9643ea8Slogwang  * Return a 32-bit hash of the given string.
59a9643ea8Slogwang  */
60a9643ea8Slogwang static __inline uint32_t
hash32_str(const void * buf,uint32_t hash)61a9643ea8Slogwang hash32_str(const void *buf, uint32_t hash)
62a9643ea8Slogwang {
63a9643ea8Slogwang 	const unsigned char *p = buf;
64a9643ea8Slogwang 
65a9643ea8Slogwang 	while (*p)
66a9643ea8Slogwang 		hash = HASHSTEP(hash, *p++);
67a9643ea8Slogwang 
68a9643ea8Slogwang 	return hash;
69a9643ea8Slogwang }
70a9643ea8Slogwang 
71a9643ea8Slogwang /*
72a9643ea8Slogwang  * Return a 32-bit hash of the given string, limited by N.
73a9643ea8Slogwang  */
74a9643ea8Slogwang static __inline uint32_t
hash32_strn(const void * buf,size_t len,uint32_t hash)75a9643ea8Slogwang hash32_strn(const void *buf, size_t len, uint32_t hash)
76a9643ea8Slogwang {
77a9643ea8Slogwang 	const unsigned char *p = buf;
78a9643ea8Slogwang 
79a9643ea8Slogwang 	while (*p && len--)
80a9643ea8Slogwang 		hash = HASHSTEP(hash, *p++);
81a9643ea8Slogwang 
82a9643ea8Slogwang 	return hash;
83a9643ea8Slogwang }
84a9643ea8Slogwang 
85a9643ea8Slogwang /*
86a9643ea8Slogwang  * Return a 32-bit hash of the given string terminated by C,
87a9643ea8Slogwang  * (as well as 0).  This is mainly here as a helper for the
88a9643ea8Slogwang  * namei() hashing of path name parts.
89a9643ea8Slogwang  */
90a9643ea8Slogwang static __inline uint32_t
hash32_stre(const void * buf,int end,const char ** ep,uint32_t hash)91a9643ea8Slogwang hash32_stre(const void *buf, int end, const char **ep, uint32_t hash)
92a9643ea8Slogwang {
93a9643ea8Slogwang 	const unsigned char *p = buf;
94a9643ea8Slogwang 
95a9643ea8Slogwang 	while (*p && (*p != end))
96a9643ea8Slogwang 		hash = HASHSTEP(hash, *p++);
97a9643ea8Slogwang 
98a9643ea8Slogwang 	if (ep)
99a9643ea8Slogwang 		*ep = p;
100a9643ea8Slogwang 
101a9643ea8Slogwang 	return hash;
102a9643ea8Slogwang }
103a9643ea8Slogwang 
104a9643ea8Slogwang /*
105a9643ea8Slogwang  * Return a 32-bit hash of the given string, limited by N,
106a9643ea8Slogwang  * and terminated by C (as well as 0).  This is mainly here
107a9643ea8Slogwang  * as a helper for the namei() hashing of path name parts.
108a9643ea8Slogwang  */
109a9643ea8Slogwang static __inline uint32_t
hash32_strne(const void * buf,size_t len,int end,const char ** ep,uint32_t hash)110a9643ea8Slogwang hash32_strne(const void *buf, size_t len, int end, const char **ep,
111a9643ea8Slogwang     uint32_t hash)
112a9643ea8Slogwang {
113a9643ea8Slogwang 	const unsigned char *p = buf;
114a9643ea8Slogwang 
115a9643ea8Slogwang 	while (*p && (*p != end) && len--)
116a9643ea8Slogwang 		hash = HASHSTEP(hash, *p++);
117a9643ea8Slogwang 
118a9643ea8Slogwang 	if (ep)
119a9643ea8Slogwang 		*ep = p;
120a9643ea8Slogwang 
121a9643ea8Slogwang 	return hash;
122a9643ea8Slogwang }
123a9643ea8Slogwang 
124a9643ea8Slogwang #ifdef _KERNEL
125a9643ea8Slogwang /*
126a9643ea8Slogwang  * Hashing function from Bob Jenkins. Implementation in libkern/jenkins_hash.c.
127a9643ea8Slogwang  */
128a9643ea8Slogwang uint32_t jenkins_hash(const void *, size_t, uint32_t);
129a9643ea8Slogwang uint32_t jenkins_hash32(const uint32_t *, size_t, uint32_t);
130a9643ea8Slogwang 
131a9643ea8Slogwang uint32_t murmur3_32_hash(const void *, size_t, uint32_t);
132a9643ea8Slogwang uint32_t murmur3_32_hash32(const uint32_t *, size_t, uint32_t);
133a9643ea8Slogwang 
134a9643ea8Slogwang #endif /* _KERNEL */
135a9643ea8Slogwang 
136a9643ea8Slogwang #endif /* !_SYS_HASH_H_ */
137