FreeNOS
HashTable.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __LIB_LIBSTD_HASHTABLE_H
19#define __LIB_LIBSTD_HASHTABLE_H
20
21#include "Types.h"
22#include "Macros.h"
23#include "Vector.h"
24#include "List.h"
25#include "ListIterator.h"
26#include "HashFunction.h"
27#include "Associative.h"
28#include "Assert.h"
29
31#define HASHTABLE_DEFAULT_SIZE 64
32
44template <class K, class V> class HashTable : public Associative<K,V>
45{
46 public:
47
51 class Bucket
52 {
53 public:
54
59 {
60 }
61
68 Bucket(K k, V v)
69 : key(k), value(v)
70 {
71 }
72
76 Bucket(const Bucket & b)
77 : key(b.key), value(b.value)
78 {
79 }
80
86 bool operator == (const Bucket & b) const
87 {
88 return key == b.key && value == b.value;
89 }
90
94 bool operator != (const Bucket & b) const
95 {
96 return !(key == b.key && value == b.value);
97 }
98
101
104 };
105
112 : m_table(size)
113 {
114 assert(size > 0);
115
116 m_count = ZERO;
117
118 // Fill the Vector with empty Bucket Lists.
119 for (Size i = 0; i < m_table.size(); i++)
120 m_table.insert(List<Bucket>());
121 }
122
133 virtual bool insert(const K & key, const V & value)
134 {
135
136 Size idx = hash(key, m_table.size());
137
138 // See if the given key exists. Overwrite if so.
139 for (ListIterator<Bucket> i(m_table[idx]); i.hasCurrent(); i++)
140 {
141 if (i.current().key == key)
142 {
143 i.current().value = value;
144 return true;
145 }
146 }
147
148 // Key does not exist. Append it.
149 m_table[idx].append(Bucket(key, value));
150 m_count++;
151 return true;
152 }
153
162 virtual bool append(const K & key, const V & value)
163 {
164
165 // Always append
166 m_table[hash(key, m_table.size())].append(Bucket(key, value));
167 m_count++;
168 return true;
169 }
170
178 virtual int remove(const K & key)
179 {
180 int removed = 0;
181
182 for (ListIterator<Bucket> i(m_table[hash(key, m_table.size())]); i.hasCurrent(); )
183 {
184 if (i.current().key == key)
185 {
186 i.remove();
187 m_count--;
188 removed++;
189 }
190 else
191 i++;
192 }
193 return removed;
194 }
195
201 virtual Size size() const
202 {
203 return m_table.size();
204 }
205
211 virtual Size count() const
212 {
213 return m_count;
214 }
215
221 virtual List<K> keys() const
222 {
223 List<K> lst;
224
225 for (Size i = 0; i < m_table.count(); i++)
226 for (ListIterator<Bucket> j(m_table[i]); j.hasCurrent(); j++)
227 if (!lst.contains(j.current().key))
228 lst << j.current().key;
229
230 return lst;
231 }
232
236 virtual List<K> keys(const V & value) const
237 {
238 List<K> lst;
239
240 for (Size i = 0; i < m_table.count(); i++)
241 for (ListIterator<Bucket> j(m_table[i]); j.hasCurrent(); j++)
242 if (j.current().value == value && !lst.contains(j.current().key))
243 lst << j.current().key;
244
245 return lst;
246 }
247
253 virtual List<V> values() const
254 {
255 List<V> lst;
256
257 for (Size i = 0; i < m_table.count(); i++)
258 for (ListIterator<Bucket> j(m_table[i]); j.hasCurrent(); j++)
259 lst << j.current().value;
260
261 return lst;
262 }
263
269 virtual List<V> values(const K & key) const
270 {
271 List<V> lst;
272
273 for (ListIterator<Bucket> i(m_table[hash(key, m_table.size())]); i.hasCurrent(); i++)
274 if (i.current().key == key)
275 lst << i.current().value;
276
277 return lst;
278 }
279
287 virtual const V * get(const K & key) const
288 {
289 const List<Bucket> & lst = m_table[hash(key, m_table.size())];
290
291 for (ListIterator<Bucket> i(lst); i.hasCurrent(); i++)
292 if (i.current().key == key)
293 return &i.current().value;
294
295 return ZERO;
296 }
297
307 virtual const V & at(const K & key) const
308 {
309 const List<Bucket> & lst = m_table[hash(key, m_table.size())];
310
311 for (ListIterator<Bucket> i(lst); i.hasCurrent(); i++)
312 if (i.current().key == key)
313 return i.current().value;
314
315 return m_table[0].head()->data.value;
316 }
317
325 virtual const V value(const K & key, const V defaultValue = V()) const
326 {
327 const List<Bucket> & lst = m_table[hash(key, m_table.size())];
328
329 for (ListIterator<Bucket> i(lst); i.hasCurrent(); i++)
330 if (i.current().key == key)
331 return i.current().value;
332
333 return defaultValue;
334 }
335
342 {
343 return m_table;
344 }
345
349 V & operator[](const K & key)
350 {
351 return (V &) at(key);
352 }
353
357 const V & operator[](const K & key) const
358 {
359 return (const V &) at(key);
360 }
361
362 private:
363
366
369};
370
376#endif /* __LIB_LIBSTD_HASHTABLE_H */
#define HASHTABLE_DEFAULT_SIZE
Default size of the HashTable internal table.
Definition HashTable.h:31
Associatives are containers that provide a mapping of keys to values.
Definition Associative.h:40
Describes a bucket in the HashTable, for collision avoidance.
Definition HashTable.h:52
Bucket(const Bucket &b)
Copy constructor.
Definition HashTable.h:76
V value
Value of the item.
Definition HashTable.h:103
Bucket(K k, V v)
Constructor.
Definition HashTable.h:68
Bucket()
Default constructor.
Definition HashTable.h:58
bool operator!=(const Bucket &b) const
Inequality operator.
Definition HashTable.h:94
bool operator==(const Bucket &b) const
Comparision operator.
Definition HashTable.h:86
K key
Key for this item.
Definition HashTable.h:100
Efficient key -> value lookups.
Definition HashTable.h:45
virtual const V value(const K &key, const V defaultValue=V()) const
Return the first value for the given key.
Definition HashTable.h:325
virtual int remove(const K &key)
Remove value(s) for the given key.
Definition HashTable.h:178
virtual List< K > keys(const V &value) const
Retrieve list of Keys for the given value.
Definition HashTable.h:236
HashTable(Size size=HASHTABLE_DEFAULT_SIZE)
Class constructor.
Definition HashTable.h:111
Vector< List< Bucket > > & table()
Get the internal Vector with Buckets.
Definition HashTable.h:341
virtual const V & at(const K &key) const
Returns a reference to the first value for the given key.
Definition HashTable.h:307
Size m_count
Number of values in the buckets.
Definition HashTable.h:368
virtual List< V > values(const K &key) const
Retrieve values for the given key inside the Association.
Definition HashTable.h:269
const V & operator[](const K &key) const
Constant index operator.
Definition HashTable.h:357
virtual const V * get(const K &key) const
Returns the first value for the given key.
Definition HashTable.h:287
virtual List< K > keys() const
Retrieve all keys inside the Association.
Definition HashTable.h:221
virtual Size size() const
Get the size of the HashTable.
Definition HashTable.h:201
virtual Size count() const
Get the number of values stored in the HashTable.
Definition HashTable.h:211
virtual bool insert(const K &key, const V &value)
Inserts the given item to the HashTable.
Definition HashTable.h:133
V & operator[](const K &key)
Modifiable index operator.
Definition HashTable.h:349
virtual List< V > values() const
Retrieve all values inside the Association.
Definition HashTable.h:253
virtual bool append(const K &key, const V &value)
Append a new item.
Definition HashTable.h:162
Vector< List< Bucket > > m_table
Internal table.
Definition HashTable.h:365
Iterate through a List.
virtual bool hasCurrent() const
Check if there is a current item on the List.
T data
Item of this node.
Definition List.h:57
Simple linked list template class.
Definition List.h:37
Node * head()
Get the first Node on the list.
Definition List.h:254
virtual bool contains(const T t) const
Check whether an element is on the List.
Definition List.h:219
Vectors are dynamically resizeable Arrays.
Definition Vector.h:42
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
Size hash(const String &key, Size mod)
Compute a hash using the FNV algorithm.
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43