Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

hash.inc
Go to the documentation of this file.
1 
29 #pragma once
30 
31 #pragma GCC visibility push(default)
32 namespace abacus {
33 
34 
35 template <class KeyType, class ItemType>
37  const KeyType &key,
38  const ItemType &item) :
39 key_(key),
40  item_(item),
41  next_(nullptr)
42 { }
43 
44 
45 template <class KeyType, class ItemType>
46 std::ostream &operator<<(std::ostream &out, const AbaHashItem<KeyType, ItemType> &rhs)
47 {
48  return out << '(' << rhs.key_ << ',' << rhs.item_ << ')';
49 }
50 
51 
52 template <class KeyType, class ItemType>
53 inline AbaHashItem<KeyType, ItemType> * AbaHashItem<KeyType,
54  ItemType>::next()
55 {
56  return next_;
57 }
58 
59 
60 template <class KeyType, class ItemType>
61 AbaHash<KeyType, ItemType>::AbaHash(int size)
62  : size_(size), nCollisions_(0), iter_(nullptr)
63 {
64  table_ = new AbaHashItem<KeyType, ItemType>* [size];
65 
66  for (int i = 0; i < size; i++)
67  table_[i] = nullptr;
68 }
69 
70 
71 template <class KeyType, class ItemType>
72 AbaHash<KeyType, ItemType>::~AbaHash()
73 {
74  AbaHashItem<KeyType, ItemType> *h1;
75  AbaHashItem<KeyType, ItemType> *h2;
76  int i;
77 
78  for (i = 0; i < size_; i++) {
79  if((h1 = table_[i]))
80  while (h1) {
81  h2 = h1->next_;
82  delete h1;
83  h1 = h2;
84  }
85  }
86  delete [] table_;
87 }
88 
89 
90 template <class KeyType, class ItemType>
91 std::ostream &operator<<(std::ostream &out, const AbaHash<KeyType, ItemType> &hash)
92 {
93  AbaHashItem<KeyType, ItemType> *h;
94  const int s = hash.size();
95 
96  for (int i = 0; i < s; i++) {
97  h = hash.table_[i];
98  if (h) {
99  out << i << ':';
100  while(h) {
101  out << *h << ' ';
102  h = h->next();
103  }
104  out << std::endl;
105  }
106  }
107  return out;
108 }
109 
110 
111 template <class KeyType, class ItemType>
112 void AbaHash<KeyType, ItemType>::insert(
113  const KeyType &key,
114  const ItemType &item)
115 {
116  AbaHashItem<KeyType, ItemType> *h = new AbaHashItem<KeyType, ItemType>(key, item);
117  int slotNum = hf(key);
118 
119  if (table_[slotNum]) ++nCollisions_;
120  h->next_ = table_[slotNum];
121  table_[slotNum] = h;
122 }
123 
124 
125 template <class KeyType, class ItemType>
126 void AbaHash<KeyType, ItemType>::overWrite(
127  const KeyType &key,
128  const ItemType &item)
129 {
131  int slotNum = hf(key);
132  if (table_[slotNum]) ++nCollisions_;
133 
134  AbaHashItem<KeyType, ItemType> *h = table_[slotNum];
135 
137 
139  while (h) {
140  if (h->key_ == key) {
141  h->item_ = item;
142  return;
143  }
144  h = h->next_;
145  }
146 
148  h = new AbaHashItem<KeyType, ItemType>(key, item);
149  h->next_ = table_[slotNum];
150  table_[slotNum] = h;
151 }
152 
153 
154 template <class KeyType, class ItemType>
155 const ItemType * AbaHash<KeyType, ItemType>::find(const KeyType &key) const
156 {
157  const AbaHashItem<KeyType, ItemType> *slot;
158 
159  slot = table_[hf(key)];
160 
161  while (slot) {
162  if (key == slot->key_) return &(slot->item_);
163  slot = slot->next_;
164  }
165  return nullptr;
166 }
167 
168 template <class KeyType, class ItemType>
169 ItemType * AbaHash<KeyType, ItemType>::find(const KeyType &key)
170 {
171  AbaHashItem<KeyType, ItemType> *slot;
172 
173  slot = table_[hf(key)];
174 
175  while (slot) {
176  if (key == slot->key_) return &(slot->item_);
177  slot = slot->next_;
178  }
179  return 0;
180 }
181 
182 template <class KeyType, class ItemType>
183 bool AbaHash<KeyType, ItemType>::find (const KeyType &key, const ItemType &item) const
184 {
185  const AbaHashItem<KeyType, ItemType> *slot;
186 
187  slot = table_[hf(key)];
188 
189  while (slot) {
190  if (key == slot->key_ && slot->item_ == item)
191  return true;
192  slot = slot->next_;
193  }
194  return false;
195 }
196 
197 
198 template <class KeyType, class ItemType>
199 ItemType *AbaHash<KeyType, ItemType>::initializeIteration(const KeyType &key)
200 {
201  iter_ = table_[hf(key)];
202  while (iter_) {
203  if (key == iter_->key_) return &(iter_->item_);
204  iter_ = iter_->next_;
205  }
206  return nullptr;
207 }
208 
209 template <class KeyType, class ItemType>
210 const ItemType *AbaHash<KeyType, ItemType>::initializeIteration(const KeyType &key) const
211 {
212  iter_ = table_[hf(key)];
213  while (iter_) {
214  if (key == iter_->key_) return &(iter_->item_);
215  iter_ = iter_->next_;
216  }
217  return nullptr;
218 }
219 
220 template <class KeyType, class ItemType>
221 ItemType *AbaHash<KeyType, ItemType>::next(const KeyType &key)
222 {
223  if (iter_ == nullptr) return nullptr;
224  iter_ = iter_->next_;
225 
226  while (iter_) {
227  if (key == iter_->key_) return &(iter_->item_);
228  iter_ = iter_->next();
229  }
230  return nullptr;
231 }
232 
233 template <class KeyType, class ItemType>
234 const ItemType *AbaHash<KeyType, ItemType>::next(const KeyType &key) const
235 {
236  if (iter_ == nullptr) return nullptr;
237  iter_ = iter_->next_;
238 
239  while (iter_) {
240  if (key == iter_->key_) return &(iter_->item_);
241  iter_ = iter_->next();
242  }
243  return nullptr;
244 }
245 
246 template <class KeyType, class ItemType>
247 int AbaHash<KeyType, ItemType>::remove(const KeyType &key)
248 {
249  // remove(): find the slot and return if it is empty
250  AbaHashItem<KeyType, ItemType> *h1;
251  AbaHashItem<KeyType, ItemType> *h2;
252  int slotNum = hf(key);
253 
254  h1 = table_[slotNum];
255  if (h1 == 0)
256  return 1;
257 
258  // check if the first item is being removed
259  if (h1->key_ == key) {
260  table_[slotNum] = h1->next_;
261  delete h1;
262  return 0;
263  }
264 
265  // otherwise, go through the linked list
266  while ((h2 = h1->next_)) {
267  if (h2->key_ == key) {
268  h1->next_ = h2->next_;
269  delete h2;
270  return 0;
271  }
272  h1 = h2;
273  }
274  return 1;
275 }
276 
277 
278 template <class KeyType, class ItemType>
279 int AbaHash<KeyType, ItemType>::remove(const KeyType &key, const ItemType &item)
280 {
281  // remove(): find the slot and return if it is empty
282  AbaHashItem<KeyType, ItemType> *h1;
283  AbaHashItem<KeyType, ItemType> *h2;
284  int slotNum = hf(key);
285 
286  h1 = table_[slotNum];
287  if (h1 == nullptr)
288  return 1;
289 
290  // check \a key and \a item of the head of the list
291  if (h1->key_ == key && h1->item_ == item) {
292  table_[slotNum] = h1->next_;
293  delete h1;
294  return 0;
295  }
296 
297  // check \a key and \a item of the other elements of the list
298  while ((h2 = h1->next_)) {
299  if (h2->key_ == key && h2->item_ == item) {
300  h1->next_ = h2->next_;
301  delete h2;
302  return 0;
303  }
304  h1 = h2;
305  }
306  return 1;
307 }
308 
309 
310 template <class KeyType, class ItemType>
311 inline int AbaHash<KeyType, ItemType>::size() const
312 {
313  return size_;
314 }
315 
316 
317 template <class KeyType, class ItemType>
318 inline int AbaHash<KeyType, ItemType>::nCollisions() const
319 {
320  return nCollisions_;
321 }
322 
323 
324 template <class KeyType, class ItemType>
325 inline int AbaHash<KeyType, ItemType>::hf(int key) const
326 {
327  if (key < 0) key = -key;
328 
329  double x = key*0.6180339887;
330 
331  return (int) (size()*(x-floor(x)));
332 }
333 
334 
335 template <class KeyType, class ItemType>
336 inline int AbaHash<KeyType, ItemType>::hf(unsigned key) const
337 {
338  double x = key*0.6180339887;
339 
340  return (int) (size()*fmod(x, 1.0));
341 }
342 
343 
344 template <class KeyType, class ItemType>
345 int AbaHash<KeyType, ItemType>::hf(const string &str) const
346 {
347  const int prime = 516595003;
348  const int mult = 314159;
349 
350  string::size_type s = str.size();
351  int h = 0;
352  for (string::size_type i = 0; i < s; i++) {
353  h += (h ^ (h >> 1)) + mult * (unsigned char) str[i];
354  while (h >= prime)
355  h -= prime;
356  }
357 
358  return h % size();
359 }
360 
361 
362 template <class KeyType, class ItemType>
363 void AbaHash<KeyType, ItemType>::resize(int newSize)
364 {
365  // check the value of \a newSize
366  if (newSize <= 0) {
367  Logger::ifout() << "AbaHash::resize(): new size of hash table must be positive.\n";
368  OGDF_THROW_PARAM(AlgorithmFailureException, ogdf::AlgorithmFailureCode::Hash);
369  }
370 
371  // allocate a new hash table
372  /* We have to set the entries of the new hash table to 0 that we
373  * can insert the items in the linear lists of the slots in a simple way later.
374  */
375  AbaHashItem<KeyType, ItemType> **newTable;
376 
377  newTable = new AbaHashItem<KeyType, ItemType>* [newSize];
378 
379  for (int i = 0; i < newSize; i++)
380  newTable[i] = nullptr;
381 
382  // insert all elements of the old table into the new table
383  /* We cannot make copies of slots of the old hash tables but have to reinsert
384  * all elements into the new hash table since the hash function might have
385  * changed. For efficieny we move each hash item to the new slot.
386  *
387  * We replace already here the old size with the new size of the hash table,
388  * because we need the hash function according to the new size.
389  */
390  int oldSize = size_;
391  size_ = newSize;
392 
393  for (int i = 0; i < oldSize; i++) {
394  if (table_[i]) {
395  // move the items to the corresponding new slots
396  AbaHashItem<KeyType, ItemType> *current = table_[i];
397  AbaHashItem<KeyType, ItemType> *next;
398 
399  while (current) {
400  int slotNum = hf(current->key_);
401  next = current->next_;
402 
403  current->next_ = newTable[slotNum];
404  newTable[slotNum] = current;
405  current = next;
406  }
407 
408  }
409  }
410 
411  // replace the old table by the new one
412  delete [] table_;
413  table_ = newTable;
414 }
415 
416 }
417 #pragma GCC visibility pop
abacus
Definition: ILPClusterPlanarity.h:50
ogdf::tlp::Attribute::size
@ size
ogdf::AlgorithmFailureCode::Hash
@ Hash
abacus::AbaHashItem::AbaHashItem
AbaHashItem(const KeyType &key, const ItemType &item)
The constructor.
ogdf::operator<<
std::ostream & operator<<(std::ostream &os, const ogdf::Array< E, INDEX > &a)
Prints array a to output stream os.
Definition: Array.h:983
OGDF_THROW_PARAM
#define OGDF_THROW_PARAM(CLASS, PARAM)
Replacement for throw.
Definition: exceptions.h:71
Minisat::Internal::hash
static uint32_t hash(uint32_t x)
Definition: Map.h:39
Minisat::Internal::remove
static void remove(V &ts, const T &t)
Definition: Alg.h:37
Minisat::Internal::find
static bool find(V &ts, const T &t)
Definition: Alg.h:48