• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINIKIN_HASHER_H
18 #define MINIKIN_HASHER_H
19 
20 #include <cstdint>
21 
22 #include <string>
23 
24 #include "minikin/Macros.h"
25 
26 namespace minikin {
27 
28 // Provides a Jenkins hash implementation.
29 class Hasher {
30 public:
Hasher()31     Hasher() : mHash(0u) {}
32 
update(uint32_t data)33     IGNORE_INTEGER_OVERFLOW inline Hasher& update(uint32_t data) {
34         mHash += data;
35         mHash += (mHash << 10);
36         mHash ^= (mHash >> 6);
37         return *this;
38     }
39 
update(int32_t data)40     inline Hasher& update(int32_t data) {
41         update(static_cast<uint32_t>(data));
42         return *this;
43     }
44 
update(uint64_t data)45     inline Hasher& update(uint64_t data) {
46         update(static_cast<uint32_t>(data));
47         update(static_cast<uint32_t>(data >> 32));
48         return *this;
49     }
50 
update(float data)51     inline Hasher& update(float data) {
52         union {
53             float f;
54             uint32_t i;
55         } bits;
56         bits.f = data;
57         return update(bits.i);
58     }
59 
updateShorts(const uint16_t * data,uint32_t length)60     inline Hasher& updateShorts(const uint16_t* data, uint32_t length) {
61         update(length);
62         uint32_t i;
63         for (i = 0; i < (length & -2); i += 2) {
64             update((uint32_t)data[i] | ((uint32_t)data[i + 1] << 16));
65         }
66         if (length & 1) {
67             update((uint32_t)data[i]);
68         }
69         return *this;
70     }
71 
updateString(const std::string & str)72     inline Hasher& updateString(const std::string& str) {
73         uint32_t size = str.size();
74         update(size);
75         uint32_t i;
76         for (i = 0; i < (size & -4); i += 4) {
77             update((uint32_t)str[i] | ((uint32_t)str[i + 1] << 8) | ((uint32_t)str[i + 2] << 16) |
78                    ((uint32_t)str[i + 3] << 24));
79         }
80         if (size & 3) {
81             uint32_t data = str[i];
82             data |= ((size & 3) > 1) ? ((uint32_t)str[i + 1] << 8) : 0;
83             data |= ((size & 3) > 2) ? ((uint32_t)str[i + 2] << 16) : 0;
84             update(data);
85         }
86         return *this;
87     }
88 
hash()89     IGNORE_INTEGER_OVERFLOW inline uint32_t hash() {
90         uint32_t hash = mHash;
91         hash += (hash << 3);
92         hash ^= (hash >> 11);
93         hash += (hash << 15);
94         return hash;
95     }
96 
97 private:
98     uint32_t mHash;
99 };
100 
101 }  // namespace minikin
102 
103 #endif  // MINIKIN_HASHER_H
104