CACAO
hashtable.hpp
Go to the documentation of this file.
1 /* src/toolbox/hashtable.hpp - functions for internal hashtables
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #ifndef HASHTABLE_HPP_
27 #define HASHTABLE_HPP_ 1
28 
29 #include "config.h"
30 
31 #include <cassert> // for assert
32 #include <cstddef> // for size_t
33 #include <new> // for operator new
34 
35 #include "mm/memory.hpp" // for MemoryAllocator
36 
37 #include "toolbox/util.hpp" // for is_power_of_two, etc
38 
39 #include "vm/types.hpp" // for u4
40 #include "vm/utf8.hpp" // for Utf8String
41 
42 class Mutex;
43 
44 
45 /***
46  * An instrusive hash table using open addressing.
47  *
48  * Entries stored in the table must conform to the following interface:
49  * @code
50  * struct Entry {
51  * Entry();
52  * Entry(const Entry&);
53  *
54  * // An Entry constructed with it's default constructor
55  * // must return true for is_empty().
56  * bool is_empty() const;
57  * bool is_occupied() const;
58  *
59  * // make this an inline function that always
60  * // returns false for an insert only table
61  * bool is_deleted() const;
62  *
63  * void set_empty();
64  * void set_occupied(const T&);
65  *
66  * // only required if you want to remove elements from the table,
67  * // an insert-only table will work without it.
68  * void set_deleted();
69  *
70  * // there must be an overload for any T that you want to insert
71  * // into the table
72  * void set_occupied(const T&);
73  *
74  * // these are only ever called on occupied entries
75  * bool operator==(const T&);
76  * size_t hash() const;
77  * };
78  * @endcode
79  *
80  * An entry can be in one of three states: empty, occupied and deleted.
81  *
82  * Each table entry must have an unique key that identifies it.
83  * The key must be stored in the entry itself, it is not stored separately in
84  * the table.
85  *
86  * After inserting an element its key and the key's hash code may never
87  * change.
88  *
89  * Calling find(), insert() or remove() on the table invalidates pointers
90  * to elements in the table, EntryRefs and Iterators.
91  *
92  * This hash table is not thread safe.
93  *
94  * If you want an insert only hash table Entry should not have a set_deleted()
95  * method. If the is_deleted() method is inline and always returns false
96  * it can be inlined away, and there should be no overhead.
97  *
98  * @tparam Entry The type of element stored in the table.
99  * Must conform to the interface mentioned above
100  * Should be small, a pointer is optimal.
101  * @tparam Allocator STL style allocator for Entries.
102  *
103  * @note
104  * The design of the hash table is taken from CPython
105  * as presented in the book `Beautiful Code',
106  * and Google's sparsehash (https://code.google.com/p/sparsehash)
107  *
108  * @Cpp11 Use C++11 move semantics to move entries on resize instead of copying them
109  */
110 template<typename _Entry,
111  typename _Allocator = MemoryAllocator<_Entry> >
112 struct HashTable {
113  typedef _Entry Entry;
114  typedef _Allocator Allocator;
115 
116  static const size_t DEFAULT_INITIAL_CAPACITY = 256;
117  static const size_t DEFAULT_LOAD_FACTOR = 85;
118 
119  /***
120  * Creates an empty hash table.
121  *
122  * @Cpp11 Make this a constexpr
123  */
125  capacity(0),
126  count(0),
127  deleted(0),
128  threshold(0),
130 
131  HashTable(size_t initial_capacity, size_t load_factor = DEFAULT_LOAD_FACTOR) {
132  assert(initial_capacity > 0);
133 
134  this->capacity = initial_capacity;
135  this->count = 0;
136  this->load_factor = load_factor;
137 
138  allocate_table();
139  };
140 
142 
143  /***
144  * A reference to an entry in the table.
145  *
146  * Can be obtained via find(), and used with insert() and remove()
147  * for insertion and deletion with a single hash lookup.
148  */
149  class EntryRef {
150  public:
151  /***
152  * Check if entry pointed to by ref is valid.
153  *
154  * Accessing an invalid entry leads to undefined behaviour.
155  */
156  operator bool() const { return occupied; }
157 
158  /***
159  * Access to refs entry.
160  * Only use this if operator bool() returns true
161  *
162  * You MUST NOT alter the key of entry
163  */
164  Entry *operator->() { return entry; }
165  Entry &operator*() { return *entry; }
166  private:
167  EntryRef(Entry *e, bool occupied) : entry(e), occupied(occupied) {}
168 
170  bool occupied;
171 
172  friend struct HashTable;
173  };
174 
175  /***
176  * An STL style iterator that can be used to traverse all
177  * elements stored in the table
178  */
179  class Iterator {
180  public:
181  bool operator==(Iterator it) const { return pos == it.pos; }
182  bool operator!=(Iterator it) const { return pos != it.pos; }
183 
185  pos = next_occupied(pos, end);
186 
187  return *this;
188  }
190  Iterator it(*this);
191  ++(*this);
192  return it;
193  }
194 
195  Entry& operator*() { return *pos; }
196  Entry* operator->() { return pos; }
197  private:
198  Iterator(Entry *pos, Entry *end) : pos(pos), end(end) {}
199 
201 
202  friend struct HashTable;
203  };
204 
205  /***
206  * Find entry for key.
207  * Iff no such entry exists converting the returned ref to bool yields false.
208  * The returned EntryRef can be used to insert or remove items.
209  *
210  * T must have a member function:
211  * size_t hash() const;
212  * T must be equality comparable to an Entry
213  */
214  template<typename T>
215  EntryRef find(const T& t) {
216  // make sure table has at least one unoccupied entry
217  if ((count + deleted) >= threshold)
218  grow_table(capacity + 1);
219 
221 
222  size_t hash = t.hash();
223  size_t index = hash;
224  size_t perturb = hash;
225 
226  Entry *insert_pos = NULL;
227  bool occupied = false;
228 
229  while (1) {
230  Entry *e = entries + fast_modulo(index, capacity);
231 
232  if (e->is_empty()) {
233  if (insert_pos) {
234  // No entry for key found, could be inserted at insert_pos
235  break;
236  } else {
237  // No entry for key found, could be inserted at e
238  insert_pos = e;
239  break;
240  }
241  } else if (e->is_deleted() && !insert_pos) {
242  // Not the entry we're looking for, but we could insert here
243  insert_pos = e;
244  } else if (*e == t) {
245  // Found entry
246  insert_pos = e;
247  occupied = true;
248  break;
249  }
250 
251  // e does not contain the entry we are looking for
252  // or a deleted entry, keep searching
253  index = (5 * index) + 1 + perturb;
254  perturb >>= 5;
255  }
256 
257  // single point of return for RVO
258  return EntryRef(insert_pos, occupied);
259  }
260 
261  /***
262  * Insert element into table.
263  * Does nothing if it is already present.
264  *
265  * Returns the newly inserted or already present element.
266  *
267  * T must have a member function:
268  * size_t hash() const;
269  * T must be equality comparable to an Entry
270  * T must be assignable to an Entry
271  */
272  template<typename T>
273  Entry& insert(const T& t) {
274  return insert(find(t), t);
275  }
276 
277  /***
278  * Insert into entry pointed to by ref.
279  * Does nothing if it is already present.
280  *
281  * Returns the newly inserted or already present element.
282  *
283  * `e' MUST have the same key as was used to obtain `ref'.
284  *
285  * T must have a member function:
286  * size_t hash() const;
287  * T must be equality comparable to an Entry
288  * T must be assignable to an Entry
289  */
290  template<typename T>
291  Entry& insert(EntryRef ref, const T& t) {
292  if (ref) {
293  return *ref;
294  } else {
295  return update(ref, t);
296  }
297  }
298 
299  /***
300  * Insert or update element in table.
301  *
302  * Returns the newly inserted element.
303  *
304  * T must have a member function:
305  * size_t hash() const;
306  * T must be equality comparable to an Entry
307  * T must be assignable to an Entry
308  */
309  template<typename T>
310  Entry& update(const T& t) {
311  return update(find(t), t);
312  }
313 
314  /***
315  * Insert or update element in table.
316  *
317  * Returns the newly inserted element.
318  *
319  * `e' MUST have the same key as was used to obtain `ref'.
320  *
321  * T must have a member function:
322  * size_t hash() const;
323  * T must be equality comparable to an Entry
324  * T must be assignable to an Entry
325  */
326  template<typename T>
327  Entry& update(EntryRef ref, const T& t) {
328  if (ref->is_empty()) {
329  // insert into empty entry
330  count++;
331  } else if (ref->is_deleted()) {
332  // overwrite deleted entry
333  count++;
334  deleted--;
335  }
336 
337  ref->set_occupied(t);
338 
339  return *ref;
340  }
341 
342  /**
343  * Utility function for hashtables that store key value pairs
344  */
345  template<typename Key, typename Val>
346  Entry& insert(const Key& k, const Val& v) {
347  return insert(find(k), Entry(k, v));
348  }
349 
350  /**
351  * Utility function for hashtables that store key value pairs
352  */
353  template<typename Key, typename Val>
354  Entry& insert(EntryRef ref, const Key& k, const Val& v) {
355  return insert(ref, Entry(k, v));
356  }
357 
358  /**
359  * Utility function for hashtables that store key value pairs
360  */
361  template<typename Key, typename Val>
362  Entry& update(const Key& k, const Val& v) {
363  return update(find(k), Entry(k, v));
364  }
365 
366  /**
367  * Utility function for hashtables that store key value pairs
368  */
369  template<typename Key, typename Val>
370  Entry& update(EntryRef ref, const Key& k, const Val& v) {
371  return update(ref, Entry(k, v));
372  }
373 
374  /***
375  * Remove entry pointed to by ref.
376  *
377  * `e' MUST have the same key as was used to obtain `ref'.
378  *
379  * T must have a member function:
380  * size_t hash() const;
381  * T must be equality comparable to an Entry
382  */
383  void remove(EntryRef ref) {
384  if (ref) {
385  ref->set_deleted();
386 
387  count--;
388  deleted++;
389  }
390  }
391 
392  /***
393  * Remove element from table.
394  *
395  * T must have a member function:
396  * size_t hash() const;
397  * T must be equality comparable to an Entry
398  */
399  template<typename T>
400  void remove(const T& t) {
401  remove(find(t));
402  }
403 
404  /***
405  * Remove all entries from the table.
406  */
407  void clear() {
408  count = 0;
409  deleted = 0;
410 
411  for (Entry *e = entries, *end = entries + capacity; e != end; ++e) {
412  e->set_empty();
413  }
414  }
415 
416  /***
417  * Makes sure the table has enough space for at least n entries
418  */
419  void reserve(size_t n) {
420  if (n <= capacity)
421  return;
422 
423  grow_table(n);
424  }
425 
426  /***
427  * Change the tables load factor.
428  * This never triggers a resizing, a resize may be triggered by the next
429  * call to find, insert, update or erase.
430  */
432  assert(load_factor > 0);
433  assert(load_factor < 100);
434 
435  this->load_factor = load_factor;
437  }
438 
439  /***
440  * Access to all occupied entries in table.
441  */
442  Iterator begin() {
443  Entry *begin = entries;
444  Entry *end = entries + capacity;
445 
446  // skip to first entry that is occupied
447  if (begin != end && !begin->is_occupied())
448  begin = next_occupied(begin, end);
449 
450  return Iterator(begin, end);
451  }
452 
453  Iterator end() {
454  return Iterator(entries + capacity, entries + capacity);
455  }
456 
457  size_t size() { return count; }
458  bool empty() { return count == 0; }
459 private:
460  HashTable(const HashTable&); // non-copyable
461  HashTable& operator=(const HashTable&); // non-assignable
462 
464  return capacity > (count + deleted);
465  }
466 
467  /**
468  * Increase capacity, re-allocate table and copy over all old entries
469  */
470  void grow_table(size_t new_capacity) {
471  Entry *old_entries = entries;
472  size_t old_capacity = capacity;
473 
474  capacity = next_power_of_two(new_capacity);
475 
476  assert(capacity > 0);
477  assert(capacity > old_capacity);
478  allocate_table();
479 
480  // re-insert all entries
481  for (Entry *it = old_entries, *end = old_entries + old_capacity; it != end; ++it) {
482  if (it->is_occupied()) {
483  // We use an optimized version of the hash lookup here.
484  // We can omit some checks since we know that,
485  // a) the table contains no deleted entries,
486  // b) every entry we insert has a unique key
487 
488  size_t hash = it->hash();
489  size_t index = hash;
490  size_t perturb = hash;
491 
492  while (1) {
493  Entry& e = entries[fast_modulo(index, capacity)];
494 
495  if (e.is_empty()) {
496  e.set_occupied(*it);
497  break;
498  }
499 
500  // e does not contain the entry we are looking for
501  // or a deleted entry, keep searching
502  index = (5 * index) + 1 + perturb;
503  perturb >>= 5;
504  }
505  }
506  }
507 
508  // free old table
509  destroy(old_entries, old_capacity);
510  }
511 
512  /***
513  * Allocate table with given capacity.
514  * Also recomputes resize threshold
515  */
516  void allocate_table() {
517  assert(is_power_of_two(capacity));
518 
519  deleted = 0;
521 
522  // allocate new table
523  entries = allocator.allocate(capacity);
524  assert(capacity == 0 || entries != NULL);
525 
526  // initialize table entries
527  new (entries) Entry[capacity]();
528  }
529 
530  void destroy(Entry *es, size_t sz) {
531  for (Entry *it = es, *end = it + sz; it != end; ++it) {
532  it->~Entry();
533  }
534 
535  allocator.deallocate(es, sz);
536  }
537 
539  threshold = (capacity * load_factor) / 100;
540  }
541 
543  if (current == end) return current;
544 
545  do {
546  ++current;
547  } while (current != end && !current->is_occupied());
548 
549  return current;
550  }
551 
552  Entry *entries; // the table of entries
553  size_t capacity; // number of elements the table can hold
554  size_t count; // number of elements stored in the table
555  size_t deleted; // number of deleted elements in the table
556  size_t threshold; // table will be resized when `count' gets
557  // greater than `threshold'
558  size_t load_factor; // used to compute threshold
559  Allocator allocator; // used to allocate table
560 };
561 
562 
563 /***
564  * A HashTable entry that uses Utf8Strings as key.
565  * Useful for using a HashTable as a hash map.
566  *
567  * @code
568  * typedef HashTable<NameValueEntry<int> > HashMap;
569  *
570  * HashMap map;
571  * Utf8String key = ...;
572  *
573  * map.insert(key, 5);
574  *
575  * int i = *map.find(key);
576  * @endcode
577  *
578  * The NULL string is forbidden as key
579  *
580  * @Cpp11 Add a templated typedef of HashTable that makes using it as a hash map easier.
581  */
582 template<typename Value>
586 
587  Utf8String name() const { return _name; }
588  Value& value() { return _value; }
589  const Value& value() const { return _value; }
590 private:
593 
594  /// Interface to HashTable
595 
596  size_t hash() const { return _name.hash(); }
597 
598  bool is_empty() const { return _name == (utf*) 0; }
599  bool is_deleted() const { return _name == (utf*) 1; }
600  bool is_occupied() const { return _name > (utf*) 1; }
601 
602  void set_empty() { _name = (utf*) 0; }
603  void set_deleted() { _name = (utf*) 1; }
604  void set_occupied(const NameValuePair& n) { (*this) = n; }
605 
606  bool operator==(Utf8String u) const { return _name == u; }
607  bool operator==(const NameValuePair& n) const { return _name == n._name; }
608 
609  template<typename T, typename A>
610  friend struct HashTable;
611 };
612 
613 /***
614  * Same as NameValuePair, but for insert only hash tables.
615  */
616 template<typename Value>
620 
621  Utf8String key() const { return _name; }
622  Value& value() { return _value; }
623  const Value& value() const { return _value; }
624 
625  Value *operator->() { return _value; }
626  Value &operator*() { return *_value; }
627 private:
630 
631  /// Interface to HashTable
632 
633  size_t hash() const { return _name.hash(); }
634 
635  bool is_empty() const { return _name == (utf*) 0; }
636  bool is_deleted() const { return _name == (utf*) 1; }
637  bool is_occupied() const { return _name > (utf*) 1; }
638 
639  void set_empty() { _name = (utf*) 0; }
640  void set_deleted() { _name = (utf*) 1; }
641  void set_occupied(const InsertOnlyNameValuePair& n) { (*this) = n; }
642 
643  bool operator==(Utf8String u) const { return _name == u; }
644  bool operator==(const InsertOnlyNameValuePair& n) const { return _name == n._name; }
645 
646  template<typename T, typename A>
647  friend struct HashTable;
648 };
649 
650 
651 /***
652  * A HashTable entry that uses a Utf8String as key.
653  * Useful for using a HashTable as an intrusive hash map.
654  *
655  * The key is not stored separately in the entry, Value must store
656  * and provide access to the key.
657  *
658  * The type Value must have members for accessing the key:
659  * @code
660  * Utf8String key() const;
661  * void set_key(Utf8String);
662  * @endcode
663  *
664  * The NULL string is forbidden as key
665  */
666 template<typename Value>
667 struct NamedEntry : Value {
669  NamedEntry(const Value& v) : Value(v) {}
670 private:
671  using Value::key;
672  using Value::set_key;
673 
674  /// Interface to HashTable
675 
676  size_t hash() const { return key().hash(); }
677 
678  bool is_empty() const { return key() == (utf*) 0; }
679  bool is_deleted() const { return key() == (utf*) 1; }
680  bool is_occupied() const { return key() > (utf*) 1; }
681 
682  void set_empty() { set_key((utf*) 0); }
683  void set_deleted() { set_key((utf*) 1); }
684  void set_occupied(const NamedEntry& e) { (*this) = e; }
685 
686  bool operator==(Utf8String u) const { return key() == u; }
687  bool operator==(const Value& v) const { return key() == v.key(); }
688 
689  template<typename T, typename A>
690  friend struct HashTable;
691 };
692 
693 
694 /***
695  * Same as NamedEntry, but for insert only hash tables.
696  */
697 template<typename Value>
700  InsertOnlyNamedEntry(const Value& v) : Value(v) {}
701 // InsertOnlyNamedEntry(Utf8String key, const Value& v) : Value(v) { set_key(key); }
702 private:
703  using Value::key;
704  using Value::set_key;
705 
706  /// Interface to HashTable
707 
708  size_t hash() const { return key().hash(); }
709 
710  bool is_empty() const { return key() == (utf*) 0; }
711  bool is_deleted() const { return false; }
712  bool is_occupied() const { return key() != (utf*) 0; }
713 
714  void set_empty() { set_key((utf*) 0); }
715  void set_occupied(const Value& v) { (*this) = v; }
716 
717  bool operator==(Utf8String u) const { return key() == u; }
718  bool operator==(const Value& v) const { return key() == v.key(); }
719 
720  template<typename T, typename A>
721  friend struct HashTable;
722 };
723 
724 
725 /* data structures for hashtables ********************************************
726 
727  All utf-symbols, javastrings and classes are stored in global
728  hashtables, so every symbol exists only once. Equal symbols have
729  identical pointers. The functions for adding hashtable elements
730  search the table for the element with the specified name/text and
731  return it on success. Otherwise a new hashtable element is created.
732 
733  The hashtables use external linking for handling collisions. The
734  hashtable structure contains a pointer <ptr> to the array of
735  hashtable slots. The number of hashtable slots and therefore the
736  size of this array is specified by the element <size> of hashtable
737  structure. <entries> contains the number of all hashtable elements
738  stored in the table, including those in the external chains. The
739  hashtable element structures (utf, literalstring, classinfo)
740  contain both a pointer to the next hashtable element as a link for
741  the external hash chain and the key of the element. The key is
742  computed from the text of the string or the classname by using up
743  to 8 characters.
744 
745  If the number of entries in the hashtable exceeds twice the size of
746  the hashtableslot-array it is supposed that the average length of
747  the external chains has reached a value beyond 2. Therefore the
748  functions for adding hashtable elements (utf_new, class_new,
749  literalstring_new) double the hashtableslot-array. In this
750  restructuring process all elements have to be inserted into the new
751  hashtable and new external chains must be built.
752 
753  Example for the layout of a hashtable:
754 
755 hashtable.ptr-->+-------------------+
756  | |
757  ...
758  | |
759  +-------------------+ +-------------------+ +-------------------+
760  | hashtable element |-->| hashtable element |-->| hashtable element |-->NULL
761  +-------------------+ +-------------------+ +-------------------+
762  | hashtable element |
763  +-------------------+ +-------------------+
764  | hashtable element |-->| hashtable element |-->NULL
765  +-------------------+ +-------------------+
766  | hashtable element |-->NULL
767  +-------------------+
768  | |
769  ...
770  | |
771  +-------------------+
772 
773 */
774 
775 /* hashtable ******************************************************************/
776 
777 struct hashtable {
778  Mutex *mutex; /* required for locking */
779  u4 size; /* current size of the hashtable */
780  u4 entries; /* number of entries in the table */
781  void **ptr; /* pointer to hashtable */
782 };
783 
784 
785 /* function prototypes ********************************************************/
786 
787 /* create hashtable */
789 
790 /* creates and resizes a hashtable */
792 
793 /* frees a hashtable */
795 
796 #endif // HASHTABLE_HPP_
797 
798 
799 /*
800  * These are local overrides for various environment variables in Emacs.
801  * Please do not remove this and leave it at the end of the file, where
802  * Emacs will automagically detect them.
803  * ---------------------------------------------------------------------
804  * Local variables:
805  * mode: c++
806  * indent-tabs-mode: t
807  * c-basic-offset: 4
808  * tab-width: 4
809  * End:
810  * vim:noexpandtab:sw=4:ts=4:
811  */
Iterator(Entry *pos, Entry *end)
Definition: hashtable.hpp:198
void set_deleted()
Definition: hashtable.hpp:603
NameValuePair(Utf8String name, Value v)
Definition: hashtable.hpp:585
#define hash(_i1, _i2)
Definition: peephole.c:55
std::size_t index
Entry * operator->()
Definition: hashtable.hpp:164
size_t hash() const
Interface to HashTable.
Definition: hashtable.hpp:676
Iterator & operator++()
Definition: hashtable.hpp:184
Value & value()
Definition: hashtable.hpp:588
Iterator end()
Definition: hashtable.hpp:453
void update_threshold()
Definition: hashtable.hpp:538
size_t load_factor
Definition: hashtable.hpp:558
static const size_t DEFAULT_INITIAL_CAPACITY
Definition: hashtable.hpp:116
Allocator allocator
Definition: hashtable.hpp:559
Iterator operator++(int)
Definition: hashtable.hpp:189
bool is_occupied() const
Definition: hashtable.hpp:680
Entry & update(const T &t)
Definition: hashtable.hpp:310
HashTable(size_t initial_capacity, size_t load_factor=DEFAULT_LOAD_FACTOR)
Definition: hashtable.hpp:131
bool operator==(Utf8String u) const
Definition: hashtable.hpp:606
void allocate_table()
Definition: hashtable.hpp:516
static Entry * next_occupied(Entry *current, Entry *end)
Definition: hashtable.hpp:542
Entry & insert(const T &t)
Definition: hashtable.hpp:273
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
Utf8String key() const
Definition: hashtable.hpp:621
size_t hash() const
Definition: utf8.hpp:137
Entry * entries
Definition: hashtable.hpp:552
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
void set_deleted()
Definition: hashtable.hpp:683
NamedEntry(const Value &v)
Definition: hashtable.hpp:669
static bool is_power_of_two(size_t n)
Definition: util.hpp:63
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
bool is_occupied() const
Definition: hashtable.hpp:712
void set_occupied(const NameValuePair &n)
Definition: hashtable.hpp:604
bool is_empty() const
Definition: hashtable.hpp:635
void set_empty()
Definition: hashtable.hpp:602
MachineBasicBlock * current
Entry & insert(EntryRef ref, const Key &k, const Val &v)
Utility function for hashtables that store key value pairs.
Definition: hashtable.hpp:354
void set_occupied(const InsertOnlyNameValuePair &n)
Definition: hashtable.hpp:641
void reserve(size_t n)
Definition: hashtable.hpp:419
Entry * operator->()
Definition: hashtable.hpp:196
Entry & insert(EntryRef ref, const T &t)
Definition: hashtable.hpp:291
void hashtable_free(hashtable *hash)
Definition: hashtable.cpp:98
size_t threshold
Definition: hashtable.hpp:556
bool is_deleted() const
Definition: hashtable.hpp:711
Entry & insert(const Key &k, const Val &v)
Utility function for hashtables that store key value pairs.
Definition: hashtable.hpp:346
bool is_deleted() const
Definition: hashtable.hpp:679
EntryRef(Entry *e, bool occupied)
Definition: hashtable.hpp:167
bool is_empty() const
Definition: hashtable.hpp:598
size_t hash() const
Interface to HashTable.
Definition: hashtable.hpp:596
size_t hash() const
Interface to HashTable.
Definition: hashtable.hpp:708
size_t hash() const
Interface to HashTable.
Definition: hashtable.hpp:633
bool is_deleted() const
Definition: hashtable.hpp:636
void set_load_factor(size_t load_factor)
Definition: hashtable.hpp:431
static size_t fast_modulo(size_t n, size_t modul)
fast computation of n % m.
Definition: util.hpp:72
size_t deleted
Definition: hashtable.hpp:555
void ** ptr
Definition: hashtable.hpp:781
const Value & value() const
Definition: hashtable.hpp:589
void destroy(Entry *es, size_t sz)
Definition: hashtable.hpp:530
bool operator==(Utf8String u) const
Definition: hashtable.hpp:686
Utf8String _name
Definition: hashtable.hpp:591
Entry & update(const Key &k, const Val &v)
Utility function for hashtables that store key value pairs.
Definition: hashtable.hpp:362
bool is_deleted() const
Definition: hashtable.hpp:599
_Allocator Allocator
Definition: hashtable.hpp:114
bool operator==(const InsertOnlyNameValuePair &n) const
Definition: hashtable.hpp:644
bool operator==(const NameValuePair &n) const
Definition: hashtable.hpp:607
hashtable * hashtable_resize(hashtable *hash, u4 size)
Definition: hashtable.cpp:65
size_t size()
Definition: hashtable.hpp:457
#define EXPENSIVE_ASSERT(EXPR)
An assertion that performs computations too expensive even for a normal debug build.
Definition: assert.hpp:90
bool is_occupied() const
Definition: hashtable.hpp:637
void grow_table(size_t new_capacity)
Increase capacity, re-allocate table and copy over all old entries.
Definition: hashtable.hpp:470
size_t count
Definition: hashtable.hpp:554
MIIterator e
Utf8String name() const
Definition: hashtable.hpp:587
uint32_t u4
Definition: types.hpp:46
bool is_empty() const
Definition: hashtable.hpp:678
EntryRef find(const T &t)
Definition: hashtable.hpp:215
bool operator!=(Iterator it) const
Definition: hashtable.hpp:182
Represents the result of the addition of a certain IR-variable with a certain constant.
Definition: Value.hpp:36
bool is_occupied() const
Definition: hashtable.hpp:600
Entry & update(EntryRef ref, const Key &k, const Val &v)
Utility function for hashtables that store key value pairs.
Definition: hashtable.hpp:370
InsertOnlyNameValuePair(Utf8String name, Value v)
Definition: hashtable.hpp:619
Iterator begin()
Definition: hashtable.hpp:442
bool has_empty_entries()
Definition: hashtable.hpp:463
void clear()
Definition: hashtable.hpp:407
void set_empty()
Definition: hashtable.hpp:682
Entry & update(EntryRef ref, const T &t)
Definition: hashtable.hpp:327
bool operator==(Utf8String u) const
Definition: hashtable.hpp:643
static size_t next_power_of_two(size_t n)
find the smallest power of two &gt;= n
Definition: util.hpp:41
bool operator==(const Value &v) const
Definition: hashtable.hpp:718
_Entry Entry
Definition: hashtable.hpp:113
Mutex * mutex
Definition: hashtable.hpp:778
InsertOnlyNamedEntry(const Value &v)
Definition: hashtable.hpp:700
bool is_empty() const
Definition: hashtable.hpp:710
const Value & value() const
Definition: hashtable.hpp:623
static const size_t DEFAULT_LOAD_FACTOR
Definition: hashtable.hpp:117
void set_occupied(const NamedEntry &e)
Definition: hashtable.hpp:684
HashTable & operator=(const HashTable &)
void hashtable_create(hashtable *hash, u4 size)
Definition: hashtable.cpp:38
bool operator==(Iterator it) const
Definition: hashtable.hpp:181
bool empty()
Definition: hashtable.hpp:458
size_t capacity
Definition: hashtable.hpp:553
bool operator==(Utf8String u) const
Definition: hashtable.hpp:717
bool operator==(const Value &v) const
Definition: hashtable.hpp:687
void set_occupied(const Value &v)
Definition: hashtable.hpp:715