HashMap.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #ifndef HASHMAP_H
  2. #define HASHMAP_H
  3. #include "utils/Array.h"
  4. #include "utils/List.h"
  5. #include "utils/StringBuffer.h"
  6. #include "utils/Types.h"
  7. #include "utils/Utils.h"
  8. #include <unordered_map>
  9. template<typename K, typename V>
  10. struct HashMap final {
  11. class Node {
  12. friend HashMap;
  13. friend List<Node>;
  14. K key;
  15. public:
  16. V value;
  17. const K& getKey() const {
  18. return key;
  19. }
  20. private:
  21. int next;
  22. Node(const K& key, const V& value) : key(key), value(value), next(-1) {
  23. }
  24. Node(const K& key, V&& value)
  25. : key(key), value(std::move(value)), next(-1) {
  26. }
  27. template<typename... Args>
  28. Node(const K& key, Args&&... args)
  29. : key(key), value(std::forward<Args>(args)...), next(-1) {
  30. }
  31. };
  32. template<typename N, typename R>
  33. class BaseIterator {
  34. N& nodes;
  35. int indexA;
  36. int indexB;
  37. public:
  38. BaseIterator(N& nodes, int indexA, int indexB)
  39. : nodes(nodes), indexA(indexA), indexB(indexB) {
  40. skip();
  41. }
  42. BaseIterator& operator++() {
  43. indexB++;
  44. skip();
  45. return *this;
  46. }
  47. bool operator!=(const BaseIterator& other) const {
  48. return indexA != other.indexA || indexB != other.indexB;
  49. }
  50. R& operator*() {
  51. return nodes[indexA][indexB];
  52. }
  53. private:
  54. void skip() {
  55. while(indexA < nodes.getLength() &&
  56. indexB >= nodes[indexA].getLength()) {
  57. indexA++;
  58. indexB = 0;
  59. }
  60. }
  61. };
  62. typedef BaseIterator<List<List<Node>>, Node> Iterator;
  63. typedef BaseIterator<const List<List<Node>>, const Node> ConstIterator;
  64. private:
  65. List<List<Node>> nodes;
  66. int elements;
  67. public:
  68. HashMap(int minCapacity = 8) : elements(0) {
  69. nodes.resize(1 << Utils::roundUpLog2(minCapacity));
  70. }
  71. template<typename... Args>
  72. bool tryEmplace(const K& key, Args&&... args) {
  73. rehash();
  74. Hash h = hash(key);
  75. V* v = searchList(key, h);
  76. if(v == nullptr) {
  77. nodes[h].add(key, std::forward<Args>(args)...);
  78. elements++;
  79. return false;
  80. }
  81. return true;
  82. }
  83. HashMap& add(const K& key, const V& value) {
  84. rehash();
  85. Hash h = hash(key);
  86. V* v = searchList(key, h);
  87. if(v == nullptr) {
  88. nodes[h].add(key, value);
  89. elements++;
  90. } else {
  91. *v = value;
  92. }
  93. return *this;
  94. }
  95. HashMap& add(const K& key, V&& value) {
  96. rehash();
  97. Hash h = hash(key);
  98. V* v = searchList(key, h);
  99. if(v == nullptr) {
  100. nodes[h].add(key, std::move(value));
  101. elements++;
  102. } else {
  103. *v = std::move(value);
  104. }
  105. return *this;
  106. }
  107. bool remove(const K& key) {
  108. List<Node>& list = nodes[hash(key)];
  109. for(int i = 0; i < list.getLength(); i++) {
  110. if(list[i].key == key) {
  111. list.remove(i);
  112. return true;
  113. }
  114. }
  115. return false;
  116. }
  117. const V* search(const K& key) const {
  118. return searchList(key, hash(key));
  119. }
  120. V* search(const K& key) {
  121. return searchList(key, hash(key));
  122. }
  123. bool contains(const K& key) const {
  124. return search(key) != nullptr;
  125. }
  126. HashMap& clear() {
  127. for(List<Node>& n : nodes) {
  128. n.clear();
  129. }
  130. elements = 0;
  131. return *this;
  132. }
  133. Iterator begin() {
  134. return Iterator(nodes, 0, 0);
  135. }
  136. Iterator end() {
  137. return Iterator(nodes, nodes.getLength(), 0);
  138. }
  139. ConstIterator begin() const {
  140. return ConstIterator(nodes, 0, 0);
  141. }
  142. ConstIterator end() const {
  143. return ConstIterator(nodes, nodes.getLength(), 0);
  144. }
  145. template<int L>
  146. void toString(StringBuffer<L>& s) const {
  147. s.append("[");
  148. bool c = false;
  149. for(const List<Node>& list : nodes) {
  150. for(const Node& n : list) {
  151. if(c) {
  152. s.append(", ");
  153. }
  154. s.append(n.key).append(" = ").append(n.value);
  155. c = true;
  156. }
  157. }
  158. s.append("]");
  159. }
  160. private:
  161. template<typename H>
  162. Hash hash(const H& key) const {
  163. return fullHash(key) & (nodes.getLength() - 1);
  164. }
  165. template<typename H>
  166. Hash fullHash(const H& key) const {
  167. return key.hashCode();
  168. }
  169. Hash fullHash(int key) const {
  170. return key;
  171. }
  172. void rehash() {
  173. if(elements < nodes.getLength()) {
  174. return;
  175. }
  176. HashMap<K, V> map(nodes.getLength() * 2);
  177. for(List<Node>& list : nodes) {
  178. for(Node& n : list) {
  179. map.tryEmplace(n.key, std::move(n.value));
  180. }
  181. }
  182. *this = std::move(map);
  183. }
  184. const V* searchList(const K& key, Hash h) const {
  185. for(const Node& n : nodes[h]) {
  186. if(n.key == key) {
  187. return &n.value;
  188. }
  189. }
  190. return nullptr;
  191. }
  192. V* searchList(const K& key, Hash h) {
  193. return const_cast<V*>(
  194. static_cast<const HashMap*>(this)->searchList(key, h));
  195. }
  196. };
  197. #endif