HashMap.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #ifndef HASHMAP_H
  2. #define HASHMAP_H
  3. const static int PRIMES[26] =
  4. {
  5. 17, 37, 79, 163, 331, 673, 1361, 2729, 5471, 10949, 21911, 43853, 87719,
  6. 175447, 350899, 701819, 1403641, 2807303, 5614657, 11229331, 22458671,
  7. 44917381, 89834777, 179669557, 359339171, 718678369
  8. };
  9. template<class K, class V>
  10. class HashMap
  11. {
  12. class Node
  13. {
  14. public:
  15. Node* next;
  16. K k;
  17. V v;
  18. Node(K k, V v)
  19. {
  20. next = nullptr;
  21. this->k = k;
  22. this->v = v;
  23. }
  24. };
  25. private:
  26. // hasher, key comparison
  27. int (*hasher)(K);
  28. bool (*equal)(K, K);
  29. // size specs
  30. int primeIndex;
  31. int capacity;
  32. int resizeCap;
  33. // entries
  34. Node** data;
  35. int entries;
  36. // found node
  37. K lastKey;
  38. Node* found;
  39. int lastIndex;
  40. int getHigherPrimeIndex(int lower) const
  41. {
  42. int low = 0;
  43. int high = 25;
  44. int mid;
  45. while(true)
  46. {
  47. if(low == high)
  48. {
  49. return low;
  50. }
  51. mid = (high + low) >> 1;
  52. if(PRIMES[mid] >= lower)
  53. {
  54. high = mid;
  55. }
  56. else
  57. {
  58. low = mid + 1;
  59. }
  60. }
  61. }
  62. int getHash(K k) const
  63. {
  64. int hash = ((*hasher)(k)) % capacity;
  65. return hash < 0 ? hash + capacity : hash;
  66. }
  67. void ensureCapacity()
  68. {
  69. if(entries < resizeCap)
  70. {
  71. return;
  72. }
  73. primeIndex++;
  74. if(primeIndex >= 26)
  75. {
  76. resizeCap = 2147483647;
  77. return;
  78. }
  79. int oldCapacity = capacity;
  80. capacity = PRIMES[primeIndex];
  81. resizeCap = (capacity >> 2) * 3;
  82. Node** newData = new Node*[capacity];
  83. Node* n;
  84. Node* m;
  85. int hash;
  86. for(int i = 0; i < oldCapacity; i++)
  87. {
  88. Node* old = data[i];
  89. if(old != nullptr)
  90. {
  91. hash = getHash(old->k);
  92. n = newData[hash];
  93. if(n == nullptr)
  94. {
  95. newData[hash] = old;
  96. }
  97. else
  98. {
  99. while(n->next != nullptr)
  100. {
  101. n = n->next;
  102. }
  103. n->next = old;
  104. }
  105. while(old->next != nullptr)
  106. {
  107. n = old->next;
  108. old->next = nullptr;
  109. hash = getHash(n->k);
  110. m = newData[hash];
  111. if(m == nullptr)
  112. {
  113. newData[hash] = n;
  114. }
  115. else
  116. {
  117. while(m->next != nullptr)
  118. {
  119. m = m->next;
  120. }
  121. m->next = n;
  122. }
  123. old = n;
  124. }
  125. }
  126. }
  127. delete[] data;
  128. data = newData;
  129. }
  130. public:
  131. HashMap(int initialLoad, int (*hasher)(K), bool (*equal)(K, K))
  132. {
  133. this->hasher = hasher;
  134. this->equal = equal;
  135. this->hasher = hasher;
  136. primeIndex = getHigherPrimeIndex(initialLoad);
  137. capacity = PRIMES[primeIndex];
  138. resizeCap = (capacity >> 2) * 3;
  139. data = new Node*[capacity];
  140. for(int i = 0; i < capacity; i++)
  141. {
  142. data[i] = nullptr;
  143. }
  144. entries = 0;
  145. found = nullptr;
  146. lastIndex = -1;
  147. }
  148. virtual ~HashMap()
  149. {
  150. for(int i = 0; i < capacity; i++)
  151. {
  152. Node* n = data[i];
  153. while(n != nullptr)
  154. {
  155. Node* next = n->next;
  156. delete n;
  157. n = next;
  158. }
  159. }
  160. delete[] data;
  161. }
  162. void search(K k)
  163. {
  164. lastKey = k;
  165. int hash = getHash(k);
  166. Node* n = data[hash];
  167. if(n == nullptr) // free slot, nothing found
  168. {
  169. found = nullptr;
  170. // mark index for inserting
  171. lastIndex = hash;
  172. }
  173. else
  174. {
  175. while(true)
  176. {
  177. if((*equal)(k, n->k)) // key was found
  178. {
  179. // mark existing node for overwrite / deleting
  180. found = n;
  181. lastIndex = hash;
  182. return;
  183. }
  184. if(n->next == nullptr)
  185. {
  186. break;
  187. }
  188. n = n->next;
  189. }
  190. // nothing found, mark last node for adding
  191. found = n;
  192. lastIndex = -1;
  193. }
  194. }
  195. void print() const
  196. {
  197. for(int i = 0; i < capacity; i++)
  198. {
  199. Node* n = data[i];
  200. if(n != nullptr)
  201. {
  202. std::cout << n->k << " - " << n->v;
  203. while(n->next != nullptr)
  204. {
  205. n = n->next;
  206. std::cout << ", " << n->k << " - " << n->v;
  207. }
  208. std::cout << "\n";
  209. }
  210. }
  211. }
  212. void insert(K k, V v)
  213. {
  214. search(k);
  215. insert(v);
  216. }
  217. void insert(V v)
  218. {
  219. if(found == nullptr)
  220. {
  221. if(lastIndex != -1)
  222. {
  223. // inserting into empty slot
  224. data[lastIndex] = new Node(lastKey, v);
  225. entries++;
  226. lastIndex = -1;
  227. ensureCapacity();
  228. }
  229. }
  230. else
  231. {
  232. if(lastIndex != -1)
  233. {
  234. // overwriting old value
  235. found->v = v;
  236. }
  237. else
  238. {
  239. // adding new node to list
  240. found->next = new Node(lastKey, v);
  241. entries++;
  242. ensureCapacity();
  243. }
  244. found = nullptr;
  245. }
  246. }
  247. void remove()
  248. {
  249. if(found != nullptr && lastIndex != -1)
  250. {
  251. // search previous node
  252. Node* n = data[lastIndex];
  253. if(found == n)
  254. {
  255. data[lastIndex] = n->next;
  256. delete n;
  257. }
  258. else
  259. {
  260. while(n->next != found)
  261. {
  262. n = n->next;
  263. }
  264. n->next = found->next;
  265. delete found;
  266. }
  267. entries--;
  268. found = nullptr;
  269. }
  270. }
  271. bool isFound() const
  272. {
  273. return found != nullptr && lastIndex != -1;
  274. }
  275. V getValue() const
  276. {
  277. return found->v;
  278. }
  279. int getCapacity() const
  280. {
  281. return capacity;
  282. }
  283. int getSize() const
  284. {
  285. return entries;
  286. }
  287. void forEach(void (*w)(K, V)) const
  288. {
  289. for(int i = 0; i < capacity; i++)
  290. {
  291. Node* n = data[i];
  292. if(n != nullptr)
  293. {
  294. (*w)(n->k, n->v);
  295. while(n->next != nullptr)
  296. {
  297. n = n->next;
  298. (*w)(n->k, n->v);
  299. }
  300. }
  301. }
  302. }
  303. };
  304. #endif