Embedded Template Library
1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
murmur3.h
Go to the documentation of this file.
1
2
3
/******************************************************************************
4
The MIT License(MIT)
5
6
Embedded Template Library.
7
https://github.com/ETLCPP/etl
8
https://www.etlcpp.com
9
10
Copyright(c) 2014 John Wellbelove
11
12
Permission is hereby granted, free of charge, to any person obtaining a copy
13
of this software and associated documentation files(the "Software"), to deal
14
in the Software without restriction, including without limitation the rights
15
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16
copies of the Software, and to permit persons to whom the Software is
17
furnished to do so, subject to the following conditions :
18
19
The above copyright notice and this permission notice shall be included in all
20
copies or substantial portions of the Software.
21
22
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
SOFTWARE.
29
******************************************************************************/
30
31
#ifndef ETL_MURMUR3_INCLUDED
32
#define ETL_MURMUR3_INCLUDED
33
34
#include "
platform.h
"
35
#include "
binary.h
"
36
#include "
error_handler.h
"
37
#include "
ihash.h
"
38
#include "
iterator.h
"
39
40
#include <stdint.h>
41
42
#if defined(ETL_COMPILER_KEIL)
43
#pragma diag_suppress 1300
44
#endif
45
48
49
namespace
etl
50
{
51
//***************************************************************************
55
//***************************************************************************
56
template
<
typename
THash>
57
class
murmur3
58
{
59
public
:
60
61
#if ETL_NOT_USING_64BIT_TYPES
62
ETL_STATIC_ASSERT((etl::is_same<THash, uint32_t>::value),
"Only 32 bit types supported"
);
63
#else
64
ETL_STATIC_ASSERT((etl::is_same<THash, uint32_t>::value || etl::is_same<THash, uint64_t>::value),
"Only 32 & 64 bit types supported"
);
65
#endif
66
67
typedef
THash value_type;
68
69
//*************************************************************************
72
//*************************************************************************
73
murmur3
(value_type seed_ = 0)
74
: seed(seed_)
75
{
76
reset
();
77
}
78
79
//*************************************************************************
84
//*************************************************************************
85
template
<
typename
TIterator>
86
murmur3
(TIterator
begin
,
const
TIterator
end
, value_type seed_ = 0)
87
: seed(seed_)
88
{
89
ETL_STATIC_ASSERT(
sizeof
(
typename
etl::iterator_traits<TIterator>::value_type) == 1,
"Incompatible type"
);
90
91
reset
();
92
while
(
begin
!=
end
)
93
{
94
block |=
static_cast<
value_type
>
(
static_cast<
value_type
>
(*begin) << (block_fill_count * 8U));
95
++
begin
;
96
97
if
(++block_fill_count == FULL_BLOCK)
98
{
99
add_block();
100
block_fill_count = 0;
101
block = 0;
102
}
103
104
++char_count;
105
}
106
}
107
108
//*************************************************************************
110
//*************************************************************************
111
void
reset
()
112
{
113
hash = seed;
114
char_count = 0;
115
block = 0;
116
block_fill_count = 0;
117
is_finalised =
false
;
118
}
119
120
//*************************************************************************
124
//*************************************************************************
125
template
<
typename
TIterator>
126
void
add
(TIterator
begin
,
const
TIterator
end
)
127
{
128
ETL_STATIC_ASSERT(
sizeof
(
typename
etl::iterator_traits<TIterator>::value_type) == 1,
"Incompatible type"
);
129
ETL_ASSERT
(!is_finalised, ETL_ERROR(
hash_finalised
));
130
131
while
(
begin
!=
end
)
132
{
133
block |=
static_cast<
value_type
>
(
static_cast<
value_type
>
(*begin) << (block_fill_count * 8U));
134
++
begin
;
135
136
if
(++block_fill_count == FULL_BLOCK)
137
{
138
add_block();
139
block_fill_count = 0;
140
block = 0;
141
}
142
143
++char_count;
144
}
145
}
146
147
//*************************************************************************
151
//*************************************************************************
152
void
add
(uint8_t value_)
153
{
154
// We can't add to a finalised hash!
155
ETL_ASSERT
(!is_finalised, ETL_ERROR(
hash_finalised
));
156
157
block |=
static_cast<
value_type
>
(
static_cast<
value_type
>
(value_) << (block_fill_count * 8U));
158
159
if
(++block_fill_count == FULL_BLOCK)
160
{
161
add_block();
162
block_fill_count = 0;
163
block = 0;
164
}
165
166
++char_count;
167
}
168
169
//*************************************************************************
171
//*************************************************************************
172
value_type
value
()
173
{
174
finalise();
175
return
hash;
176
}
177
178
//*************************************************************************
180
//*************************************************************************
181
operator
value_type()
182
{
183
return
value
();
184
}
185
186
private
:
187
188
//*************************************************************************
190
//*************************************************************************
191
void
add_block()
192
{
193
block *= CONSTANT1;
194
block =
rotate_left
(block, SHIFT1);
195
block *= CONSTANT2;
196
197
hash ^= block;
198
hash =
rotate_left
(hash, SHIFT2);
199
hash = (hash * MULTIPLY) + ADD;
200
}
201
202
//*************************************************************************
204
//*************************************************************************
205
void
finalise()
206
{
207
if
(!is_finalised)
208
{
209
block *= CONSTANT1;
210
block =
rotate_left
(block, SHIFT1);
211
block *= CONSTANT2;
212
213
hash ^= block;
214
hash ^= char_count;
215
hash ^= (hash >> 16U);
216
hash *= 0x85EBCA6BUL;
217
hash ^= (hash >> 13U);
218
hash *= 0xC2B2AE35UL;
219
hash ^= (hash >> 16U);
220
221
is_finalised =
true
;
222
}
223
}
224
225
bool
is_finalised;
226
uint8_t block_fill_count;
227
size_t
char_count;
228
value_type block;
229
value_type hash;
230
value_type seed;
231
232
static
ETL_CONSTANT uint8_t FULL_BLOCK = 4U;
233
static
ETL_CONSTANT value_type CONSTANT1 = 0xCC9E2D51UL;
234
static
ETL_CONSTANT value_type CONSTANT2 = 0x1B873593UL;
235
static
ETL_CONSTANT value_type SHIFT1 = 15;
236
static
ETL_CONSTANT value_type SHIFT2 = 13;
237
static
ETL_CONSTANT value_type MULTIPLY = 5;
238
static
ETL_CONSTANT value_type ADD = 0xE6546B64UL;
239
};
240
}
// namespace etl
241
242
#endif
binary.h
error_handler.h
etl::rotate_left
ETL_CONSTEXPR14 T rotate_left(T value)
Definition
binary.h:117
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition
error_handler.h:511
etl::murmur3::reset
void reset()
Resets the hash to the initial state.
Definition
murmur3.h:111
etl::murmur3::murmur3
murmur3(value_type seed_=0)
Definition
murmur3.h:73
etl::murmur3::murmur3
murmur3(TIterator begin, const TIterator end, value_type seed_=0)
Definition
murmur3.h:86
etl::murmur3::add
void add(TIterator begin, const TIterator end)
Definition
murmur3.h:126
etl::murmur3::value
value_type value()
Gets the hash value.
Definition
murmur3.h:172
etl::murmur3::add
void add(uint8_t value_)
Definition
murmur3.h:152
etl::hash_finalised
Definition
ihash.h:63
ihash.h
iterator.h
etl
Definition
absolute.h:40
etl::end
TContainer::iterator end(TContainer &container)
Definition
iterator.h:1166
etl::begin
TContainer::iterator begin(TContainer &container)
Definition
iterator.h:1136
platform.h
include
etl
murmur3.h
Generated on
for Embedded Template Library by
1.17.0