/src/adhd/third_party/superfasthash/sfh.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2010, Paul Hsieh |
2 | | * All rights reserved. |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions are met: |
6 | | * |
7 | | * * Redistributions of source code must retain the above copyright notice, this |
8 | | * list of conditions and the following disclaimer. |
9 | | * * Redistributions in binary form must reproduce the above copyright notice, |
10 | | * this list of conditions and the following disclaimer in the documentation |
11 | | * and/or other materials provided with the distribution. |
12 | | * * Neither my name, Paul Hsieh, nor the names of any other contributors to the |
13 | | * code use may not be used to endorse or promote products derived from this |
14 | | * software without specific prior written permission. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
20 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | | * POSSIBILITY OF SUCH DAMAGE. |
27 | | */ |
28 | | |
29 | | #include "sfh.h" |
30 | | |
31 | | #include <inttypes.h> |
32 | | #include <stdbool.h> |
33 | | #include <stddef.h> |
34 | | #include <stdint.h> |
35 | | #include <stdlib.h> |
36 | | #include <syslog.h> |
37 | | |
38 | | #include "cras/common/string.h" |
39 | | |
40 | | #undef get16bits |
41 | | #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) || \ |
42 | | defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TURBOC__) |
43 | | #define get16bits(d) (*((const uint16_t*)(d))) |
44 | | #endif |
45 | | |
46 | | #if !defined(get16bits) |
47 | | #define get16bits(d) \ |
48 | 13.9k | ((((uint32_t)(((const uint8_t*)(d))[1])) << 8) + \ |
49 | 13.9k | (uint32_t)(((const uint8_t*)(d))[0])) |
50 | | #endif |
51 | | |
52 | | static inline uint32_t SuperFastHash_impl(const char* data, |
53 | | int len, |
54 | 3.30k | uint32_t hash) { |
55 | 3.30k | uint32_t tmp; |
56 | 3.30k | int rem; |
57 | | |
58 | 3.30k | if (len <= 0 || data == NULL) { |
59 | 1.31k | return 0; |
60 | 1.31k | } |
61 | | |
62 | 1.99k | rem = len & 3; |
63 | 1.99k | len >>= 2; |
64 | | |
65 | | // Main loop |
66 | 8.96k | for (; len > 0; len--) { |
67 | 6.97k | hash += get16bits(data); |
68 | 6.97k | tmp = (uint32_t)(get16bits(data + 2) << 11) ^ hash; |
69 | 6.97k | hash = (hash << 16) ^ tmp; |
70 | 6.97k | data += 2 * sizeof(uint16_t); |
71 | 6.97k | hash += hash >> 11; |
72 | 6.97k | } |
73 | | |
74 | | // Handle end cases |
75 | 1.99k | switch (rem) { |
76 | 0 | case 3: |
77 | 0 | hash += get16bits(data); |
78 | 0 | hash ^= hash << 16; |
79 | 0 | hash ^= (uint32_t)(((signed char)data[sizeof(uint16_t)]) << 18); |
80 | 0 | hash += hash >> 11; |
81 | 0 | break; |
82 | 0 | case 2: |
83 | 0 | hash += get16bits(data); |
84 | 0 | hash ^= hash << 11; |
85 | 0 | hash += hash >> 17; |
86 | 0 | break; |
87 | 1.54k | case 1: |
88 | 1.54k | hash += (uint32_t)((signed char)*data); |
89 | 1.54k | hash ^= hash << 10; |
90 | 1.54k | hash += hash >> 1; |
91 | 1.99k | } |
92 | | |
93 | | // Force "avalanching" of final 127 bits |
94 | 1.99k | hash ^= hash << 3; |
95 | 1.99k | hash += hash >> 5; |
96 | 1.99k | hash ^= hash << 4; |
97 | 1.99k | hash += hash >> 17; |
98 | 1.99k | hash ^= hash << 25; |
99 | 1.99k | hash += hash >> 6; |
100 | | |
101 | 1.99k | return hash; |
102 | 1.99k | } |
103 | | |
104 | | static inline uint32_t SuperFastHash_debug(const char* data, |
105 | | int len, |
106 | 0 | uint32_t hash) { |
107 | 0 | uint32_t out = SuperFastHash_impl(data, len, hash); |
108 | 0 |
|
109 | 0 | char* escaped_data = escape_string(data, len); |
110 | 0 | syslog(LOG_INFO, "SuperFastHash(\"%s\", 0x%08" PRIx32 ") = 0x%08" PRIx32, |
111 | 0 | escaped_data, hash, out); |
112 | 0 | free(escaped_data); |
113 | 0 | return out; |
114 | 0 | } |
115 | | |
116 | 3.30k | uint32_t SuperFastHash(const char* data, int len, uint32_t hash) { |
117 | 3.30k | #define SUPER_FAST_HASH_DEBUG false |
118 | 3.30k | if (SUPER_FAST_HASH_DEBUG) { |
119 | 0 | return SuperFastHash_debug(data, len, hash); |
120 | 0 | } |
121 | 3.30k | return SuperFastHash_impl(data, len, hash); |
122 | 3.30k | } |