aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
hashFunc_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49
50// to help IDE parser
51#include <cstring>
52
54
55#ifndef DOXYGEN_SHOULD_SKIP_THIS
56
57namespace gum {
58
59 // Update the hash function to take into account a resize of the hash table
60 template < typename Key >
61 INLINE void HashFuncBase< Key >::resize(const Size new_size) {
62 // things work properly only for hashtables with at least 2 elements
63 if (new_size < 2) {
64 GUM_ERROR(SizeError,
65 "the size of the hashtable must be at least 2 but a size of "
66 << new_size << " was provided to the resize function.");
67 }
68
69 hash_log2_size_ = _hashTableLog2_(new_size);
70 hash_size_ = Size(1) << hash_log2_size_;
71 hash_mask_ = hash_size_ - 1;
72 right_shift_ = HashFuncConst::offset - hash_log2_size_;
73 }
74
75 // Returns the hash table size as known by the hash function
76 template < typename Key >
77 INLINE Size HashFuncBase< Key >::size() const {
78 return hash_size_;
79 }
80
81 // ===========================================================================
82
83 // constructor
84 template < typename Key >
86 static_assert(std::is_integral< Key >::value && sizeof(Key) <= sizeof(Size),
87 "Error: you used HashFuncSmallKey for a key which cannot be "
88 "converted (without narrowing) into a gum::Size");
89 }
90
91 // Returns the value of a key as a Size
92 template < typename Key >
93 INLINE Size HashFuncSmallKey< Key >::castToSize(const Key& key) {
94 return Size(key);
95 }
96
97 // Returns the hashed value of a key.
98 template < typename Key >
99 INLINE Size HashFuncSmallKey< Key >::operator()(const Key& key) const {
100 return (castToSize(key) * HashFuncConst::gold) >> this->right_shift_;
101 }
102
103 // ===========================================================================
104
105 // constructor
106 template < typename Key >
108 static_assert(sizeof(Key) < sizeof(Size),
109 "Error: you used HashFuncSmallCastKey for a key whose size "
110 "is longer than or equal to that of gum::Size");
111 }
112
113 // Returns the value of a key as a Size
114 template < typename Key >
115 INLINE Size HashFuncSmallCastKey< Key >::castToSize(const Key& key) {
116 // the code for MVSC differs from the code of the other compilers for
117 // speed-up reasons: according to godbolt.org, the first code
118 // should be twice faster than the second one
119# ifdef _MSC_VER
121# else
122 Size result = 0;
123 memcpy(&result, &key, sizeof(Key));
124 return result;
125# endif /* _MSC_VER */
126 }
127
128 // Returns the hashed value of a key.
129 template < typename Key >
130 INLINE Size HashFuncSmallCastKey< Key >::operator()(const Key& key) const {
131 return (castToSize(key) * HashFuncConst::gold) >> this->right_shift_;
132 }
133
134 // ===========================================================================
135
136 // constructor
137 template < typename Key >
139 static_assert(sizeof(Key) == sizeof(Size),
140 "Error: using HashFuncMediumCastKey for a key whose size "
141 "is different from that of a gum::Size");
142 }
143
144 // Returns the value of a key as a Size
145 template < typename Key >
146 INLINE Size HashFuncMediumCastKey< Key >::castToSize(const Key& key) {
147 return *((Size*)(&key));
148 }
149
150 // Returns the hashed value of a key.
151 template < typename Key >
152 INLINE Size HashFuncMediumCastKey< Key >::operator()(const Key& key) const {
153 return (castToSize(key) * HashFuncConst::gold) >> this->right_shift_;
154 }
155
156 // ===========================================================================
157
158 // constructor
159 template < typename Key >
161 static_assert(sizeof(Key) == 2 * sizeof(Size),
162 "Error: you used HashFuncLargeCastKey for a key whose size "
163 "is different from twice that of a gum::Size");
164 }
165
166 // Returns the value of a key as a Size
167 template < typename Key >
168 INLINE Size HashFuncLargeCastKey< Key >::castToSize(const Key& key) {
169 const Size* ptr = reinterpret_cast< const Size* >(&key);
170 return ptr[0] ^ ptr[1];
171 }
172
173 // Returns the hashed value of a key.
174 template < typename Key >
175 INLINE Size HashFuncLargeCastKey< Key >::operator()(const Key& key) const {
176 return (castToSize(key) * HashFuncConst::gold) >> this->right_shift_;
177 }
178
179 // ===========================================================================
180
181 // Returns the value of a key as a Size
182 template < typename Key1, typename Key2 >
183 INLINE Size HashFunc< std::pair< Key1, Key2 > >::castToSize(const std::pair< Key1, Key2 >& key) {
185 + HashFunc< Key2 >::castToSize(key.second);
186 }
187
188 // Returns the hashed value of a key.
189 template < typename Key1, typename Key2 >
190 INLINE Size
191 HashFunc< std::pair< Key1, Key2 > >::operator()(const std::pair< Key1, Key2 >& key) const {
192 return (castToSize(key) * HashFuncConst::gold) >> this->right_shift_;
193 }
194
195 // ===========================================================================
196
197 // Returns the hashed value of a key.
198 template < typename Type >
199 INLINE Size HashFunc< RefPtr< Type > >::castToSize(const RefPtr< Type >& key) {
200 return HashFunc< Type* >::castToSize(key._refCountPtr_());
201 }
202
203 // Returns the hashed value of a key.
204 template < typename Type >
205 INLINE Size HashFunc< RefPtr< Type > >::operator()(const RefPtr< Type >& key) const {
206 return (castToSize(key) * HashFuncConst::gold) & this->hash_mask_;
207 }
208
209} /* namespace gum */
210
211#endif /* DOXYGEN_SHOULD_SKIP_THIS */
Size size() const
Returns the hash table size as known by the hash function.
void resize(const Size new_size)
Update the hash function to take into account a resize of the hash table.
virtual Size operator()(const Key &key) const override final
Computes the hashed value of a key.
HashFuncLargeCastKey()
Class constructor.
static Size castToSize(const Key &key)
Cast key to the expected type.
static Size castToSize(const Key &key)
Returns the value of a key as a Size.
virtual Size operator()(const Key &key) const override final
Computes the hashed value of a key.
HashFuncMediumCastKey()
Class constructor.
HashFuncSmallCastKey()
Class constructor.
static Size castToSize(const Key &key)
Returns the value of a key as a Size.
virtual Size operator()(const Key &key) const override final
Computes the hashed value of a key.
static constexpr Size small_key_mask_
An additional mask to ensure that keys with fewer bits than Size are cast correctly.
Definition hashFunc.h:323
static Size castToSize(const Key &key)
Returns the value of a key as a Size.
virtual Size operator()(const Key &key) const override final
Computes the hashed value of a key.
HashFuncSmallKey()
Class constructor.
This class should be useless as only its specializations should be used.
Definition hashFunc.h:487
Smart pointers.
Definition refPtr.h:136
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
unsigned int _hashTableLog2_(const Size nb)
Returns the size in bits - 1 necessary to store the smallest power of 2 greater than or equal to nb.
Classes providing basic hash functions for hash tables.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
static constexpr Size pi
Definition hashFunc.h:100
static constexpr Size offset
Definition hashFunc.h:103
static constexpr Size gold
Definition hashFunc.h:98