Skip to content

Commit ebf833a

Browse files
vyazelenkomikeb01
authored andcommitted
[C] Common hash functions. (aeron-io#1178)
* [C] Fix includes. * [C] Simply mask out the key_hash_code in the *_to_ptr_hash_map since they already use FNV-1a hash function. * [C] Add 64 bit hash functions. * [C] Fix includes. * [C] Use `aeron_hash_64` for all hashmaps. * [C] Increase default load factor to 0.65. * [C] Fold 64 bit hash into 32 bit value to retain entropy of the higher bits when masking.
1 parent 60442bc commit ebf833a

15 files changed

+95
-17
lines changed

aeron-client/src/main/c/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ endif ()
4141
set(SOURCE
4242
collections/aeron_array_to_ptr_hash_map.c
4343
collections/aeron_bit_set.c
44+
collections/aeron_hashing.c
4445
collections/aeron_int64_counter_map.c
4546
collections/aeron_int64_to_ptr_hash_map.c
4647
collections/aeron_int64_to_tagged_ptr_hash_map.c
@@ -103,6 +104,7 @@ set(SOURCE
103104
set(HEADERS
104105
collections/aeron_array_to_ptr_hash_map.h
105106
collections/aeron_bit_set.h
107+
collections/aeron_hashing.h
106108
collections/aeron_int64_counter_map.h
107109
collections/aeron_int64_to_ptr_hash_map.h
108110
collections/aeron_int64_to_tagged_ptr_hash_map.h

aeron-client/src/main/c/collections/aeron_array_to_ptr_hash_map.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "util/aeron_bitutil.h"
2525
#include "util/aeron_strutil.h"
2626
#include "util/aeron_error.h"
27+
#include "collections/aeron_hashing.h"
2728
#include "collections/aeron_map.h"
2829
#include "aeron_alloc.h"
2930

@@ -54,9 +55,9 @@ inline uint64_t aeron_array_hash(const uint8_t *arr, size_t length)
5455
return aeron_fnv_64a_buf((uint8_t *)arr, length);
5556
}
5657

57-
inline size_t aeron_array_to_ptr_hash_map_hash_key(uint64_t key, size_t mask)
58+
inline size_t aeron_array_to_ptr_hash_map_hash_key(uint64_t key_hash_code, size_t mask)
5859
{
59-
return (size_t)((key * 31) & mask);
60+
return aeron_hash(key_hash_code, mask);
6061
}
6162

6263
inline bool aeron_array_to_ptr_hash_map_compare(

aeron-client/src/main/c/collections/aeron_bit_set.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "aeron_bit_set.h"
17+
#include "collections/aeron_bit_set.h"
1818

1919
extern int aeron_bit_set_stack_alloc(
2020
size_t bit_set_length, uint64_t *static_array, size_t static_array_len, aeron_bit_set_t *bit_set);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2014-2021 Real Logic Limited.
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+
* https://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+
#include "collections/aeron_hashing.h"
18+
19+
extern uint32_t aeron_hash_code(uint64_t value);
20+
21+
extern size_t aeron_hash(uint64_t value, size_t mask);
22+
23+
extern size_t aeron_even_hash(uint64_t value, size_t mask);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2014-2021 Real Logic Limited.
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+
* https://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 AERON_HASHING_H
18+
#define AERON_HASHING_H
19+
20+
#include <stddef.h>
21+
#include <stdint.h>
22+
23+
inline uint32_t aeron_hash_code(uint64_t value)
24+
{
25+
uint64_t x = value;
26+
27+
x = (x ^ (x >> 30u)) * UINT64_C(0xbf58476d1ce4e5b9);
28+
x = (x ^ (x >> 27u)) * UINT64_C(0x94d049bb133111eb);
29+
x = x ^ (x >> 31u);
30+
31+
return (uint32_t)x ^ (uint32_t)(x >> 32u);
32+
}
33+
34+
inline size_t aeron_hash(uint64_t value, size_t mask)
35+
{
36+
uint32_t hash = aeron_hash_code(value);
37+
return (size_t)(hash & mask);
38+
}
39+
40+
inline size_t aeron_even_hash(uint64_t value, size_t mask)
41+
{
42+
uint32_t hash = aeron_hash_code(value);
43+
hash = (hash << 1u) - (hash << 8u);
44+
return (size_t)(hash & mask);
45+
}
46+
47+
#endif //AERON_HASHING_H

aeron-client/src/main/c/collections/aeron_int64_counter_map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "aeron_int64_counter_map.h"
17+
#include "collections/aeron_int64_counter_map.h"
1818

1919
extern size_t aeron_int64_counter_map_hash_key(int64_t key, size_t mask);
2020

aeron-client/src/main/c/collections/aeron_int64_counter_map.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "util/aeron_platform.h"
2424
#include "util/aeron_bitutil.h"
25+
#include "collections/aeron_hashing.h"
2526
#include "collections/aeron_map.h"
2627
#include "aeron_alloc.h"
2728

@@ -38,9 +39,7 @@ aeron_int64_counter_map_t;
3839

3940
inline size_t aeron_int64_counter_map_hash_key(int64_t key, size_t mask)
4041
{
41-
uint64_t hash = ((uint64_t)key << UINT64_C(1)) - ((uint64_t)key << UINT64_C(8));
42-
43-
return (size_t)(hash & mask);
42+
return aeron_even_hash((uint64_t)key, mask);
4443
}
4544

4645
inline int aeron_int64_counter_map_init(
@@ -78,7 +77,6 @@ inline void aeron_int64_counter_map_delete(aeron_int64_counter_map_t *map)
7877
inline int aeron_int64_counter_map_rehash(aeron_int64_counter_map_t *map, size_t new_entries_length)
7978
{
8079
size_t mask = new_entries_length - 1;
81-
map->resize_threshold = (size_t)((new_entries_length / 2) * map->load_factor);
8280

8381
int64_t *tmp_entries;
8482

@@ -114,6 +112,7 @@ inline int aeron_int64_counter_map_rehash(aeron_int64_counter_map_t *map, size_t
114112

115113
map->entries = tmp_entries;
116114
map->entries_length = new_entries_length;
115+
map->resize_threshold = (size_t)((new_entries_length / 2) * map->load_factor);
117116

118117
return 0;
119118
}

aeron-client/src/main/c/collections/aeron_int64_to_ptr_hash_map.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "util/aeron_platform.h"
2323
#include "util/aeron_bitutil.h"
2424
#include "util/aeron_error.h"
25+
#include "collections/aeron_hashing.h"
2526
#include "collections/aeron_map.h"
2627
#include "aeron_alloc.h"
2728

@@ -38,7 +39,7 @@ aeron_int64_to_ptr_hash_map_t;
3839

3940
inline size_t aeron_int64_to_ptr_hash_map_hash_key(int64_t key, size_t mask)
4041
{
41-
return (size_t)(((uint64_t)key * 31u) & mask);
42+
return aeron_hash((uint64_t)key, mask);
4243
}
4344

4445
inline int aeron_int64_to_ptr_hash_map_init(

aeron-client/src/main/c/collections/aeron_int64_to_tagged_ptr_hash_map.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "util/aeron_platform.h"
2525
#include "util/aeron_bitutil.h"
26+
#include "collections/aeron_hashing.h"
2627
#include "collections/aeron_map.h"
2728
#include "aeron_alloc.h"
2829

@@ -50,7 +51,7 @@ aeron_int64_to_tagged_ptr_hash_map_t;
5051

5152
inline size_t aeron_int64_to_tagged_ptr_hash_map_hash_key(int64_t key, size_t mask)
5253
{
53-
return (size_t)(((uint64_t)key * 31u) & mask);
54+
return aeron_hash((uint64_t)key, mask);
5455
}
5556

5657
inline int aeron_int64_to_tagged_ptr_hash_map_init(

aeron-client/src/main/c/collections/aeron_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#ifndef AERON_AERON_MAP_H
1818
#define AERON_AERON_MAP_H
1919

20-
#define AERON_MAP_DEFAULT_LOAD_FACTOR (0.55f)
20+
#define AERON_MAP_DEFAULT_LOAD_FACTOR (0.65f)
2121

2222
#include <stdint.h>
2323

0 commit comments

Comments
 (0)