LMMS
Loading...
Searching...
No Matches
HashMap.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2018-2022 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#ifndef WATER_HASHMAP_H_INCLUDED
27#define WATER_HASHMAP_H_INCLUDED
28
29#include "Array.h"
30#include "../text/String.h"
31
32#include "CarlaScopeUtils.hpp"
33
34namespace water {
35
36//==============================================================================
43{
45 int generateHash (const int key, const int upperLimit) const noexcept { return std::abs (key) % upperLimit; }
47 int generateHash (const int64 key, const int upperLimit) const noexcept { return std::abs ((int) key) % upperLimit; }
49 int generateHash (const String& key, const int upperLimit) const noexcept { return (int) (((uint32) key.hashCode()) % (uint32) upperLimit); }
51 int generateHash (const void* key, const int upperLimit) const noexcept { return (int)(((pointer_sized_uint) key) % ((pointer_sized_uint) upperLimit)); }
52};
53
54
55//==============================================================================
97template <typename KeyType,
98 typename ValueType,
99 class HashFunctionType = DefaultHashFunctions>
101{
102private:
103 typedef PARAMETER_TYPE (KeyType) KeyTypeParameter;
104 typedef PARAMETER_TYPE (ValueType) ValueTypeParameter;
105
106public:
107 //==============================================================================
118 explicit HashMap (int numberOfSlots = defaultHashTableSize,
119 HashFunctionType hashFunction = HashFunctionType())
120 : hashFunctionToUse (hashFunction), totalNumItems (0)
121 {
122 hashSlots.insertMultiple (0, nullptr, numberOfSlots);
123 }
124
127 {
128 clear();
129 }
130
131 //==============================================================================
136 void clear()
137 {
138 for (int i = hashSlots.size(); --i >= 0;)
139 {
140 HashEntry* h = hashSlots.getUnchecked(i);
141
142 while (h != nullptr)
143 {
144 const CarlaScopedPointer<HashEntry> deleter (h);
145 h = h->nextEntry;
146 }
147
148 hashSlots.set (i, nullptr);
149 }
150
151 totalNumItems = 0;
152 }
153
154 //==============================================================================
156 inline int size() const noexcept
157 {
158 return totalNumItems;
159 }
160
165 inline ValueType operator[] (KeyTypeParameter keyToLookFor) const
166 {
167 for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
168 if (entry->key == keyToLookFor)
169 return entry->value;
170
171 return ValueType();
172 }
173
174 //==============================================================================
176 bool contains (KeyTypeParameter keyToLookFor) const
177 {
178 for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry)
179 if (entry->key == keyToLookFor)
180 return true;
181
182 return false;
183 }
184
186 bool containsValue (ValueTypeParameter valueToLookFor) const
187 {
188 for (int i = getNumSlots(); --i >= 0;)
189 for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry)
190 if (entry->value == valueToLookFor)
191 return true;
192
193 return false;
194 }
195
196 //==============================================================================
201 void set (KeyTypeParameter newKey, ValueTypeParameter newValue)
202 {
203 const int hashIndex = generateHashFor (newKey);
204
205 HashEntry* const firstEntry = hashSlots.getUnchecked (hashIndex);
206
207 for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry)
208 {
209 if (entry->key == newKey)
210 {
211 entry->value = newValue;
212 return;
213 }
214 }
215
216 hashSlots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry));
218
219 if (totalNumItems > (getNumSlots() * 3) / 2)
220 remapTable (getNumSlots() * 2);
221 }
222
224 void remove (KeyTypeParameter keyToRemove)
225 {
226 const int hashIndex = generateHashFor (keyToRemove);
227 HashEntry* entry = hashSlots.getUnchecked (hashIndex);
228 HashEntry* previous = nullptr;
229
230 while (entry != nullptr)
231 {
232 if (entry->key == keyToRemove)
233 {
234 const CarlaScopedPointer<HashEntry> deleter (entry);
235
236 entry = entry->nextEntry;
237
238 if (previous != nullptr)
239 previous->nextEntry = entry;
240 else
241 hashSlots.set (hashIndex, entry);
242
244 }
245 else
246 {
247 previous = entry;
248 entry = entry->nextEntry;
249 }
250 }
251 }
252
254 void removeValue (ValueTypeParameter valueToRemove)
255 {
256 for (int i = getNumSlots(); --i >= 0;)
257 {
258 HashEntry* entry = hashSlots.getUnchecked(i);
259 HashEntry* previous = nullptr;
260
261 while (entry != nullptr)
262 {
263 if (entry->value == valueToRemove)
264 {
265 const CarlaScopedPointer<HashEntry> deleter (entry);
266
267 entry = entry->nextEntry;
268
269 if (previous != nullptr)
270 previous->nextEntry = entry;
271 else
272 hashSlots.set (i, entry);
273
275 }
276 else
277 {
278 previous = entry;
279 entry = entry->nextEntry;
280 }
281 }
282 }
283 }
284
289 void remapTable (int newNumberOfSlots)
290 {
291 HashMap newTable (newNumberOfSlots);
292
293 for (int i = getNumSlots(); --i >= 0;)
294 for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry)
295 newTable.set (entry->key, entry->value);
296
297 swapWith (newTable);
298 }
299
305 {
306 return hashSlots.size();
307 }
308
309 //==============================================================================
311 template <class OtherHashMapType>
312 void swapWith (OtherHashMapType& otherHashMap) noexcept
313 {
314 hashSlots.swapWith (otherHashMap.hashSlots);
315 std::swap (totalNumItems, otherHashMap.totalNumItems);
316 }
317
318private:
319 //==============================================================================
321 {
322 public:
323 HashEntry (KeyTypeParameter k, ValueTypeParameter val, HashEntry* const next)
324 : key (k), value (val), nextEntry (next)
325 {}
326
327 const KeyType key;
328 ValueType value;
330
332 };
333
334public:
335 //==============================================================================
358 struct Iterator
359 {
360 Iterator (const HashMap& hashMapToIterate) noexcept
361 : hashMap (hashMapToIterate), entry (nullptr), index (0)
362 {}
363
365 : hashMap (other.hashMap), entry (other.entry), index (other.index)
366 {}
367
373 {
374 if (entry != nullptr)
375 entry = entry->nextEntry;
376
377 while (entry == nullptr)
378 {
379 if (index >= hashMap.getNumSlots())
380 return false;
381
382 entry = hashMap.hashSlots.getUnchecked (index++);
383 }
384
385 return true;
386 }
387
391 KeyType getKey() const
392 {
393 return entry != nullptr ? entry->key : KeyType();
394 }
395
399 ValueType getValue() const
400 {
401 return entry != nullptr ? entry->value : ValueType();
402 }
403
406 {
407 entry = nullptr;
408 index = 0;
409 }
410
411 Iterator& operator++() noexcept { next(); return *this; }
412 ValueType operator*() const { return getValue(); }
413 bool operator!= (const Iterator& other) const noexcept { return entry != other.entry || index != other.index; }
414 void resetToEnd() noexcept { index = hashMap.getNumSlots(); }
415
416 private:
417 //==============================================================================
420 int index;
421
422 CARLA_LEAK_DETECTOR (Iterator)
423 };
424
426 Iterator begin() const noexcept { Iterator i (*this); i.next(); return i; }
427
429 Iterator end() const noexcept { Iterator i (*this); i.resetToEnd(); return i; }
430
431private:
432 //==============================================================================
433 enum { defaultHashTableSize = 101 };
434 friend struct Iterator;
435
436 HashFunctionType hashFunctionToUse;
439
440 int generateHashFor (KeyTypeParameter key) const
441 {
442 const int hash = hashFunctionToUse.generateHash (key, getNumSlots());
443 wassert (isPositiveAndBelow (hash, getNumSlots())); // your hash function is generating out-of-range numbers!
444 return hash;
445 }
446
447 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HashMap)
448};
449
450}
451
452#endif // WATER_HASHMAP_H_INCLUDED
#define CARLA_DECLARE_NON_COPYABLE(ClassName)
Definition CarlaDefines.h:242
#define noexcept
Definition DistrhoDefines.h:72
Definition Array.h:57
Definition HashMap.h:321
const KeyType key
Definition HashMap.h:327
HashEntry(KeyTypeParameter k, ValueTypeParameter val, HashEntry *const next)
Definition HashMap.h:323
HashEntry * nextEntry
Definition HashMap.h:329
ValueType value
Definition HashMap.h:328
Definition HashMap.h:101
int getNumSlots() const noexcept
Definition HashMap.h:304
HashFunctionType hashFunctionToUse
Definition HashMap.h:436
bool containsValue(ValueTypeParameter valueToLookFor) const
Definition HashMap.h:186
void swapWith(OtherHashMapType &otherHashMap) noexcept
Definition HashMap.h:312
void set(KeyTypeParameter newKey, ValueTypeParameter newValue)
Definition HashMap.h:201
@ defaultHashTableSize
Definition HashMap.h:433
void remapTable(int newNumberOfSlots)
Definition HashMap.h:289
ValueType operator[](KeyTypeParameter keyToLookFor) const
Definition HashMap.h:165
int totalNumItems
Definition HashMap.h:438
bool contains(KeyTypeParameter keyToLookFor) const
Definition HashMap.h:176
void removeValue(ValueTypeParameter valueToRemove)
Definition HashMap.h:254
~HashMap()
Definition HashMap.h:126
int generateHashFor(KeyTypeParameter key) const
Definition HashMap.h:440
Iterator end() const noexcept
Definition HashMap.h:429
Iterator begin() const noexcept
Definition HashMap.h:426
Array< HashEntry * > hashSlots
Definition HashMap.h:437
void clear()
Definition HashMap.h:136
HashMap(int numberOfSlots=defaultHashTableSize, HashFunctionType hashFunction=HashFunctionType())
Definition HashMap.h:118
typedef PARAMETER_TYPE(KeyType) KeyTypeParameter
typedef PARAMETER_TYPE(ValueType) ValueTypeParameter
int size() const noexcept
Definition HashMap.h:156
void remove(KeyTypeParameter keyToRemove)
Definition HashMap.h:224
Definition String.h:48
register unsigned k
Definition inflate.c:946
register unsigned i
Definition inflate.c:1575
int val
Definition jpeglib.h:956
#define wassert(expression)
Definition AudioSampleBuffer.h:33
unsigned int uint32
Definition water.h:98
bool isPositiveAndBelow(Type valueToTest, Type upperLimit) noexcept
Definition MathsFunctions.h:187
long long int64
Definition water.h:100
unsigned int pointer_sized_uint
Definition water.h:113
Definition HashMap.h:43
int generateHash(const String &key, const int upperLimit) const noexcept
Definition HashMap.h:49
int generateHash(const int key, const int upperLimit) const noexcept
Definition HashMap.h:45
int generateHash(const int64 key, const int upperLimit) const noexcept
Definition HashMap.h:47
int generateHash(const void *key, const int upperLimit) const noexcept
Definition HashMap.h:51
Definition HashMap.h:359
int index
Definition HashMap.h:420
void resetToEnd() noexcept
Definition HashMap.h:414
Iterator(const HashMap &hashMapToIterate) noexcept
Definition HashMap.h:360
bool next() noexcept
Definition HashMap.h:372
ValueType getValue() const
Definition HashMap.h:399
HashEntry * entry
Definition HashMap.h:419
ValueType operator*() const
Definition HashMap.h:412
const HashMap & hashMap
Definition HashMap.h:418
Iterator(const Iterator &other) noexcept
Definition HashMap.h:364
Iterator & operator++() noexcept
Definition HashMap.h:411
void reset() noexcept
Definition HashMap.h:405
bool operator!=(const Iterator &other) const noexcept
Definition HashMap.h:413
KeyType getKey() const
Definition HashMap.h:391
ZCONST char * key
Definition crypt.c:587
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
#define const
Definition zconf.h:137