Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
HashTable.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* HashTable.h (C) 2000-2023 */
9/* */
10/* Table de hachage. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_HASHTABLE_H
13#define ARCANE_UTILS_HASHTABLE_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/MultiBuffer.h"
18#include "arcane/utils/Array.h"
19#include "arcane/utils/HashFunction.h"
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
36class ARCANE_UTILS_EXPORT HashTableBase
37{
38 public:
39
46 : m_count(0)
47 , m_nb_bucket(use_prime ? nearestPrimeNumber(table_size) : table_size)
48 {
49 }
50 virtual ~HashTableBase() {}
51
52 public:
53
58 Integer nearestPrimeNumber(Integer n);
59
60 public:
61
63 Integer count() const
64 {
65 return m_count;
66 }
67
68 protected:
69
70 void _throwNotFound ARCANE_NORETURN() const;
71
72 protected:
73
74 Integer m_count;
75 Integer m_nb_bucket;
76};
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
96template <typename KeyType, typename TraitsType>
98: public HashTableBase
99{
100 public:
101
102 typedef typename TraitsType::KeyTypeConstRef KeyTypeConstRef;
103 typedef typename TraitsType::KeyTypeValue KeyTypeValue;
104
105 public:
106
107 struct HashData
108 {
109 public:
110
111 friend class HashTableBaseT<KeyType, TraitsType>;
112
113 public:
114
115 HashData()
116 : m_key(KeyType())
117 , m_next(0)
118 {}
119
120 public:
121
127 {
128 m_key = new_key;
129 }
130
131 protected:
132
133 KeyTypeValue m_key;
134 HashData* m_next;
135 };
136
137 public:
138
146 , m_buckets(m_nb_bucket)
147 {
148 m_buckets.fill(0);
149 }
150
151 public:
152
154 bool hasKey(KeyTypeConstRef id) const
155 {
156 KeyType hf = _hash(id);
157 for (HashData* i = m_buckets[hf]; i; i = i->m_next) {
158 if (i->m_key == id)
159 return true;
160 }
161 return false;
162 }
163
165 void clear()
166 {
167 m_buckets.fill(0);
168 m_count = 0;
169 }
170
172 void resize(Integer new_table_size, bool use_prime = false)
173 {
175 if (new_table_size == 0) {
176 clear();
177 return;
178 }
179 if (use_prime)
181 //todo: supprimer l'allocation de ce tableau
182 UniqueArray<HashData*> old_buckets(m_buckets.clone());
183 m_buckets.resize(new_table_size);
184 m_buckets.fill(0);
185 for (Integer z = 0, zs = old_buckets.size(); z < zs; ++z) {
186 for (HashData* i = old_buckets[z]; i; i = i->m_next) {
187 _baseAdd(_hash(i->m_key), i->m_key, i);
188 }
189 }
190 }
191
193 void rehash()
194 {
195 //todo: supprimer l'allocation de ce tableau
196 UniqueArray<HashData*> old_buckets(m_buckets.clone());
197 m_buckets.fill(0);
198
199 for (Integer z = 0, zs = old_buckets.size(); z < zs; ++z) {
200 for (HashData* i = old_buckets[z]; i;) {
201 HashData* current = i;
202 i = i->m_next; // Il faut le faire ici, car i->m_next change avec _baseAdd
203 _baseAdd(_hash(current->m_key), current->m_key, current);
204 }
205 }
206 }
207
208 protected:
209
210 inline Integer _hash(KeyTypeConstRef id) const
211 {
212 return TraitsType::hashFunction(id) % m_nb_bucket;
213 }
214 inline HashData* _baseLookupBucket(Integer bucket, KeyTypeConstRef id) const
215 {
216 for (HashData* i = m_buckets[bucket]; i; i = i->m_next) {
217 if (i->m_key == id)
218 return i;
219 }
220 return 0;
221 }
222 inline HashData* _baseRemoveBucket(Integer bucket, KeyTypeConstRef id)
223 {
224 HashData* i = m_buckets[bucket];
225 if (i) {
226 if (i->m_key == id) {
227 m_buckets[bucket] = i->m_next;
228 --m_count;
229 return i;
230 }
231 for (; i->m_next; i = i->m_next) {
232 if (i->m_next->m_key == id) {
233 HashData* r = i->m_next;
234 i->m_next = i->m_next->m_next;
235 --m_count;
236 return r;
237 }
238 }
239 }
240 _throwNotFound();
241 }
242 inline HashData* _baseLookup(KeyTypeConstRef id) const
243 {
244 return _baseLookupBucket(_hash(id), id);
245 }
246 inline HashData* _baseRemove(KeyTypeConstRef id)
247 {
248 return _baseRemoveBucket(_hash(id), id);
249 }
250 inline void _baseAdd(Integer bucket, KeyTypeConstRef id, HashData* hd)
251 {
252 HashData* buck = m_buckets[bucket];
253 hd->m_key = id;
254 hd->m_next = buck;
255 m_buckets[bucket] = hd;
256 ++m_count;
257 }
258
259 protected:
260
261 UniqueArray<HashData*> m_buckets;
262};
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267} // namespace Arcane
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
272#endif
Classe de base d'une table de hachage pour tableaux associatifs.
Definition HashTable.h:99
void rehash()
Repositionne les données après changement de valeur des clés.
Definition HashTable.h:193
HashTableBaseT(Integer table_size, bool use_prime)
Crée une table de taille table_size.
Definition HashTable.h:144
void resize(Integer new_table_size, bool use_prime=false)
Redimensionne la table de hachage.
Definition HashTable.h:172
bool hasKey(KeyTypeConstRef id) const
true si une valeur avec la clé id est présente
Definition HashTable.h:154
void clear()
Supprime tous les éléments de la table.
Definition HashTable.h:165
Classe de base d'une table de hachage simple pour les entités.
Definition HashTable.h:37
HashTableBase(Integer table_size, bool use_prime)
Crée une table de taille table_size.
Definition HashTable.h:45
Integer m_nb_bucket
Nombre de buckets.
Definition HashTable.h:75
Integer nearestPrimeNumber(Integer n)
Retourne le nombre premier le plus proche de n par excès. Le nombre premier le plus proche et supérie...
Definition HashTable.cc:57
Integer m_count
Nombre d'éléments.
Definition HashTable.h:74
Integer count() const
Nombre d'éléments dans la table.
Definition HashTable.h:63
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
void changeKey(const KeyType &new_key)
Change la valeur de la clé.
Definition HashTable.h:126
KeyTypeValue m_key
Clé de recherche.
Definition HashTable.h:133