xref: /aosp_15_r20/external/leveldb/util/hash.cc (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
1*9507f98cSAndroid Build Coastguard Worker // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2*9507f98cSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*9507f98cSAndroid Build Coastguard Worker // found in the LICENSE file. See the AUTHORS file for names of contributors.
4*9507f98cSAndroid Build Coastguard Worker 
5*9507f98cSAndroid Build Coastguard Worker #include "util/hash.h"
6*9507f98cSAndroid Build Coastguard Worker 
7*9507f98cSAndroid Build Coastguard Worker #include <cstring>
8*9507f98cSAndroid Build Coastguard Worker 
9*9507f98cSAndroid Build Coastguard Worker #include "util/coding.h"
10*9507f98cSAndroid Build Coastguard Worker 
11*9507f98cSAndroid Build Coastguard Worker // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
12*9507f98cSAndroid Build Coastguard Worker // between switch labels. The real definition should be provided externally.
13*9507f98cSAndroid Build Coastguard Worker // This one is a fallback version for unsupported compilers.
14*9507f98cSAndroid Build Coastguard Worker #ifndef FALLTHROUGH_INTENDED
15*9507f98cSAndroid Build Coastguard Worker #define FALLTHROUGH_INTENDED \
16*9507f98cSAndroid Build Coastguard Worker   do {                       \
17*9507f98cSAndroid Build Coastguard Worker   } while (0)
18*9507f98cSAndroid Build Coastguard Worker #endif
19*9507f98cSAndroid Build Coastguard Worker 
20*9507f98cSAndroid Build Coastguard Worker namespace leveldb {
21*9507f98cSAndroid Build Coastguard Worker 
Hash(const char * data,size_t n,uint32_t seed)22*9507f98cSAndroid Build Coastguard Worker uint32_t Hash(const char* data, size_t n, uint32_t seed) {
23*9507f98cSAndroid Build Coastguard Worker   // Similar to murmur hash
24*9507f98cSAndroid Build Coastguard Worker   const uint32_t m = 0xc6a4a793;
25*9507f98cSAndroid Build Coastguard Worker   const uint32_t r = 24;
26*9507f98cSAndroid Build Coastguard Worker   const char* limit = data + n;
27*9507f98cSAndroid Build Coastguard Worker   uint32_t h = seed ^ (n * m);
28*9507f98cSAndroid Build Coastguard Worker 
29*9507f98cSAndroid Build Coastguard Worker   // Pick up four bytes at a time
30*9507f98cSAndroid Build Coastguard Worker   while (data + 4 <= limit) {
31*9507f98cSAndroid Build Coastguard Worker     uint32_t w = DecodeFixed32(data);
32*9507f98cSAndroid Build Coastguard Worker     data += 4;
33*9507f98cSAndroid Build Coastguard Worker     h += w;
34*9507f98cSAndroid Build Coastguard Worker     h *= m;
35*9507f98cSAndroid Build Coastguard Worker     h ^= (h >> 16);
36*9507f98cSAndroid Build Coastguard Worker   }
37*9507f98cSAndroid Build Coastguard Worker 
38*9507f98cSAndroid Build Coastguard Worker   // Pick up remaining bytes
39*9507f98cSAndroid Build Coastguard Worker   switch (limit - data) {
40*9507f98cSAndroid Build Coastguard Worker     case 3:
41*9507f98cSAndroid Build Coastguard Worker       h += static_cast<uint8_t>(data[2]) << 16;
42*9507f98cSAndroid Build Coastguard Worker       FALLTHROUGH_INTENDED;
43*9507f98cSAndroid Build Coastguard Worker     case 2:
44*9507f98cSAndroid Build Coastguard Worker       h += static_cast<uint8_t>(data[1]) << 8;
45*9507f98cSAndroid Build Coastguard Worker       FALLTHROUGH_INTENDED;
46*9507f98cSAndroid Build Coastguard Worker     case 1:
47*9507f98cSAndroid Build Coastguard Worker       h += static_cast<uint8_t>(data[0]);
48*9507f98cSAndroid Build Coastguard Worker       h *= m;
49*9507f98cSAndroid Build Coastguard Worker       h ^= (h >> r);
50*9507f98cSAndroid Build Coastguard Worker       break;
51*9507f98cSAndroid Build Coastguard Worker   }
52*9507f98cSAndroid Build Coastguard Worker   return h;
53*9507f98cSAndroid Build Coastguard Worker }
54*9507f98cSAndroid Build Coastguard Worker 
55*9507f98cSAndroid Build Coastguard Worker }  // namespace leveldb
56