source: Sophya/trunk/SophyaLib/BaseTools/hashtable.h@ 4022

Last change on this file since 4022 was 2805, checked in by ansari, 20 years ago

MAJ commentaires pour documentation doxygen - Reza 9 Juin 2005

File size: 4.4 KB
RevLine 
[242]1// This may look like C code, but it is really -*- C++ -*-
2
3// This is a hash table. Some implementations of the STL have one, like the
4// Modena Standard Library.
5
6#ifndef HASHTABLE_H_SEEN
7#define HASHTABLE_H_SEEN
8
9#include "machdefs.h"
10#include "pexceptions.h"
11
[552]12namespace SOPHYA {
[242]13
[2805]14//! \cond
[242]15template <class T, class K>
16struct HashtableEntry {
17 uint_4 hash;
18 K key;
19 T value;
20 HashtableEntry<T,K> *next;
21};
[2805]22//! \endcond
[242]23
24template <class T, class K>
25class Hashtable {
26public:
27 typedef uint_4 (*HashFunction)(K const& key);
28
29 Hashtable(uint_4 initialCapacity, float loadFactor) {
30 Init(initialCapacity,loadFactor);
31 }
32
33 Hashtable(int initialCapacity) {
34 Init(initialCapacity, 0.75);
35 }
36
37 Hashtable() {
38 Init(101, 0.75);
39 }
40
41 ~Hashtable() {
42 for (int i = count ; i-- > 0 ;) {
43 for (HashtableEntry<T,K>* e = table[i] ; e != NULL ; ) {
44 HashtableEntry<T,K>* ee = e->next;
45 delete e;
46 e = ee;
47 }
48 }
49 delete[] table;
50 }
51
52 void setHash(HashFunction f) {
53 hf = f;
54 }
55
56 uint_4 size() {
57 return count;
58 }
59
60 bool contains(T const& value) {
61 for (int i = count ; i-- > 0 ;) {
62 for (HashtableEntry<T,K>* e = table[i] ; e != NULL ; e = e->next) {
63 if (e->value == value) {
64 return true;
65 }
66 }
67 }
68 return false;
69 }
70
71 bool containsKey(K const& key) {
72 uint_4 hash = hf(key);
73 uint_4 index = (hash & 0x7FFFFFFF) % length;
74 for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
75 if ((e->hash == hash) && e->key == key) {
76 return true;
77 }
78 }
79 return false;
80 }
81
82 T const& get(K const& key) {
83 uint_4 hash = hf(key);
84 uint_4 index = (hash & 0x7FFFFFFF) % length;
85 for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
86 if ((e->hash == hash) && e->key == key) {
87 return e->value;
88 }
89 }
90 throw(NotFoundExc("Hashtable::get"));
91 }
92
93
94 void put(K const& key, T const& value) {
95 // Makes sure the key is not already in the hashtable.
96 uint_4 hash = hf(key);
97 uint_4 index = (hash & 0x7FFFFFFF) % length;
98 for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
99 if ((e->hash == hash) && e-> key == key) {
100 //T const& old = e.value;
101 e->value = value;
102 //return old;
103 }
104 }
105
106 if (count >= threshold) {
107 // Rehash the table if the threshold is exceeded
108 rehash();
109 return;// put(key, value);
110 }
111
112 // Creates the new entry.
113 HashtableEntry<T,K>* e = new HashtableEntry<T,K>;
114 e->hash = hash;
115 e->key = key;
116 e->value = value;
117 e->next = table[index];
118 table[index] = e;
119 count++;
120 //return null;
121 }
122
123
124 void remove(K const& key) {
125 uint_4 hash = hf(key);
126 uint_4 index = (hash & 0x7FFFFFFF) % tab.length;
127 for (HashtableEntry<T,K>* e = table[index], prev = null ; e != null ; prev = e, e = e->next) {
128 if ((e>hash == hash) && e>key == key) {
129 if (prev != NULL) {
130 prev->next = e->next;
131 } else {
132 table[index] = e->next;
133 }
134 count--;
135 //return e.value;
136 }
137 }
138 //return null;
139 }
140
141private:
142
143 void Init(uint_4 initialCapacity, float loadFactor) {
144 if ((initialCapacity == 0) || (loadFactor <= 0.0)) {
145 throw ParmError("Hashtable::Hashtable");
146 }
147 this->loadFactor = loadFactor;
148 this->length = initialCapacity;
149 this->count = 0;
150 table = new (HashtableEntry<T,K>*[initialCapacity]);
151 for (int i=0; i<length; i++) table[i] = NULL;
152 threshold = (uint_4)(initialCapacity * loadFactor);
153 hf = defaultHash;
154 }
155
156 static uint_4 defaultHash(K const& key) {
157 if (sizeof(K) <= sizeof(void*))
158 return (uint_4)(uint_8)(key);
159 else
160 return (uint_4)(uint_8)(&key);
161 }
162
163 void rehash() {
164 uint_4 oldCapacity = length;
165 HashtableEntry<T,K>** oldTable = table;
166
167 uint_4 newCapacity = oldCapacity * 2 + 1;
168 HashtableEntry<T,K>** newTable = new (HashtableEntry<T,K>*[newCapacity]);
169
170 threshold = (int)(newCapacity * loadFactor);
171 table = newTable;
172 length = newCapacity;
173
174 for (int i = oldCapacity ; i-- > 0 ;) {
175 for (HashtableEntry<T,K>* old = oldTable[i] ; old != NULL ; ) {
176 HashtableEntry<T,K>* e = old;
177 old = old->next;
178
179 int index = (e->hash & 0x7FFFFFFF) % newCapacity;
180 e->next = newTable[index];
181 newTable[index] = e;
182 }
183 }
184 delete[] oldTable;
185 }
186
187 HashtableEntry<T,K> **table;
188 uint_4 length;
189 uint_4 count;
190 uint_4 threshold;
191 float loadFactor;
192 HashFunction hf;
193};
194}
195
196#endif
Note: See TracBrowser for help on using the repository browser.