HashMap.h 5.2 KB

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