xref: /aosp_15_r20/external/cronet/base/third_party/superfasthash/superfasthash.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright (c) 2010, Paul Hsieh
2*6777b538SAndroid Build Coastguard Worker // All rights reserved.
3*6777b538SAndroid Build Coastguard Worker //
4*6777b538SAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
5*6777b538SAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are met:
6*6777b538SAndroid Build Coastguard Worker //
7*6777b538SAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright notice, this
8*6777b538SAndroid Build Coastguard Worker //   list of conditions and the following disclaimer.
9*6777b538SAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above copyright notice,
10*6777b538SAndroid Build Coastguard Worker //   this list of conditions and the following disclaimer in the documentation
11*6777b538SAndroid Build Coastguard Worker //   and/or other materials provided with the distribution.
12*6777b538SAndroid Build Coastguard Worker // * Neither my name, Paul Hsieh, nor the names of any other contributors to the
13*6777b538SAndroid Build Coastguard Worker //   code use may not be used to endorse or promote products derived from this
14*6777b538SAndroid Build Coastguard Worker //   software without specific prior written permission.
15*6777b538SAndroid Build Coastguard Worker //
16*6777b538SAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*6777b538SAndroid Build Coastguard Worker // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*6777b538SAndroid Build Coastguard Worker // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*6777b538SAndroid Build Coastguard Worker // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20*6777b538SAndroid Build Coastguard Worker // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*6777b538SAndroid Build Coastguard Worker // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*6777b538SAndroid Build Coastguard Worker // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*6777b538SAndroid Build Coastguard Worker // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*6777b538SAndroid Build Coastguard Worker // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*6777b538SAndroid Build Coastguard Worker // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*6777b538SAndroid Build Coastguard Worker // POSSIBILITY OF SUCH DAMAGE.
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
29*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
30*6777b538SAndroid Build Coastguard Worker #undef get16bits
31*6777b538SAndroid Build Coastguard Worker #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
32*6777b538SAndroid Build Coastguard Worker   || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
33*6777b538SAndroid Build Coastguard Worker #define get16bits(d) (*((const uint16_t *) (d)))
34*6777b538SAndroid Build Coastguard Worker #endif
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker #if !defined (get16bits)
37*6777b538SAndroid Build Coastguard Worker #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
38*6777b538SAndroid Build Coastguard Worker                        +(uint32_t)(((const uint8_t *)(d))[0]) )
39*6777b538SAndroid Build Coastguard Worker #endif
40*6777b538SAndroid Build Coastguard Worker 
SuperFastHash(const char * data,int len)41*6777b538SAndroid Build Coastguard Worker uint32_t SuperFastHash (const char * data, int len) {
42*6777b538SAndroid Build Coastguard Worker uint32_t hash = (uint32_t)len, tmp;
43*6777b538SAndroid Build Coastguard Worker int rem;
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker     if (len <= 0 || data == NULL) return 0;
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker     rem = len & 3;
48*6777b538SAndroid Build Coastguard Worker     len >>= 2;
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker     /* Main loop */
51*6777b538SAndroid Build Coastguard Worker     for (;len > 0; len--) {
52*6777b538SAndroid Build Coastguard Worker         hash  += get16bits (data);
53*6777b538SAndroid Build Coastguard Worker         tmp    = (uint32_t)(get16bits (data+2) << 11) ^ hash;
54*6777b538SAndroid Build Coastguard Worker         hash   = (hash << 16) ^ tmp;
55*6777b538SAndroid Build Coastguard Worker         data  += 2*sizeof (uint16_t);
56*6777b538SAndroid Build Coastguard Worker         hash  += hash >> 11;
57*6777b538SAndroid Build Coastguard Worker     }
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker     /* Handle end cases */
60*6777b538SAndroid Build Coastguard Worker     switch (rem) {
61*6777b538SAndroid Build Coastguard Worker         case 3: hash += get16bits (data);
62*6777b538SAndroid Build Coastguard Worker                 hash ^= hash << 16;
63*6777b538SAndroid Build Coastguard Worker                 hash ^=
64*6777b538SAndroid Build Coastguard Worker                     (uint32_t)(((signed char)data[sizeof (uint16_t)]) << 18);
65*6777b538SAndroid Build Coastguard Worker                 hash += hash >> 11;
66*6777b538SAndroid Build Coastguard Worker                 break;
67*6777b538SAndroid Build Coastguard Worker         case 2: hash += get16bits (data);
68*6777b538SAndroid Build Coastguard Worker                 hash ^= hash << 11;
69*6777b538SAndroid Build Coastguard Worker                 hash += hash >> 17;
70*6777b538SAndroid Build Coastguard Worker                 break;
71*6777b538SAndroid Build Coastguard Worker         case 1: hash += (uint32_t)((signed char)*data);
72*6777b538SAndroid Build Coastguard Worker                 hash ^= hash << 10;
73*6777b538SAndroid Build Coastguard Worker                 hash += hash >> 1;
74*6777b538SAndroid Build Coastguard Worker     }
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker     /* Force "avalanching" of final 127 bits */
77*6777b538SAndroid Build Coastguard Worker     hash ^= hash << 3;
78*6777b538SAndroid Build Coastguard Worker     hash += hash >> 5;
79*6777b538SAndroid Build Coastguard Worker     hash ^= hash << 4;
80*6777b538SAndroid Build Coastguard Worker     hash += hash >> 17;
81*6777b538SAndroid Build Coastguard Worker     hash ^= hash << 25;
82*6777b538SAndroid Build Coastguard Worker     hash += hash >> 6;
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker     return hash;
85*6777b538SAndroid Build Coastguard Worker }
86