1*4882a593Smuzhiyun /* SPDX-License-Identifier: LGPL-2.1 2*4882a593Smuzhiyun * 3*4882a593Smuzhiyun * Based on Paul Hsieh's (LGPG 2.1) hash function 4*4882a593Smuzhiyun * From: http://www.azillionmonkeys.com/qed/hash.html 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #define get16bits(d) (*((const __u16 *) (d))) 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun static __always_inline SuperFastHash(const char * data,int len,__u32 initval)10*4882a593Smuzhiyun__u32 SuperFastHash (const char *data, int len, __u32 initval) { 11*4882a593Smuzhiyun __u32 hash = initval; 12*4882a593Smuzhiyun __u32 tmp; 13*4882a593Smuzhiyun int rem; 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun if (len <= 0 || data == NULL) return 0; 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun rem = len & 3; 18*4882a593Smuzhiyun len >>= 2; 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /* Main loop */ 21*4882a593Smuzhiyun #pragma clang loop unroll(full) 22*4882a593Smuzhiyun for (;len > 0; len--) { 23*4882a593Smuzhiyun hash += get16bits (data); 24*4882a593Smuzhiyun tmp = (get16bits (data+2) << 11) ^ hash; 25*4882a593Smuzhiyun hash = (hash << 16) ^ tmp; 26*4882a593Smuzhiyun data += 2*sizeof (__u16); 27*4882a593Smuzhiyun hash += hash >> 11; 28*4882a593Smuzhiyun } 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /* Handle end cases */ 31*4882a593Smuzhiyun switch (rem) { 32*4882a593Smuzhiyun case 3: hash += get16bits (data); 33*4882a593Smuzhiyun hash ^= hash << 16; 34*4882a593Smuzhiyun hash ^= ((signed char)data[sizeof (__u16)]) << 18; 35*4882a593Smuzhiyun hash += hash >> 11; 36*4882a593Smuzhiyun break; 37*4882a593Smuzhiyun case 2: hash += get16bits (data); 38*4882a593Smuzhiyun hash ^= hash << 11; 39*4882a593Smuzhiyun hash += hash >> 17; 40*4882a593Smuzhiyun break; 41*4882a593Smuzhiyun case 1: hash += (signed char)*data; 42*4882a593Smuzhiyun hash ^= hash << 10; 43*4882a593Smuzhiyun hash += hash >> 1; 44*4882a593Smuzhiyun } 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun /* Force "avalanching" of final 127 bits */ 47*4882a593Smuzhiyun hash ^= hash << 3; 48*4882a593Smuzhiyun hash += hash >> 5; 49*4882a593Smuzhiyun hash ^= hash << 4; 50*4882a593Smuzhiyun hash += hash >> 17; 51*4882a593Smuzhiyun hash ^= hash << 25; 52*4882a593Smuzhiyun hash += hash >> 6; 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun return hash; 55*4882a593Smuzhiyun } 56