HashMap.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. #pragma once
  2. #include <functional>
  3. #include "Array.h"
  4. namespace Framework
  5. {
  6. template<typename K, typename V>
  7. class MapEntry
  8. {
  9. private:
  10. K key;
  11. V value;
  12. public:
  13. MapEntry()
  14. {}
  15. MapEntry(K key, V value)
  16. : key(key),
  17. value(value)
  18. {}
  19. K getKey()
  20. {
  21. return key;
  22. }
  23. V getValue()
  24. {
  25. return value;
  26. }
  27. template<typename K2, typename V2>
  28. friend class HashMap;
  29. };
  30. template<typename K, typename V>
  31. class MapIterator
  32. {
  33. private:
  34. int bucketIndex;
  35. Iterator< MapEntry<K, V> > iterator;
  36. Array< MapEntry<K, V> >** buckets;
  37. int bucketCount;
  38. public:
  39. MapIterator(Array< MapEntry<K, V> >** buckets, int bucketCount, int bucketIndex, Iterator< MapEntry<K, V> > iterator)
  40. : iterator(iterator)
  41. {
  42. while (bucketIndex < bucketCount && (!buckets[bucketIndex] || buckets[bucketIndex]->getEintragAnzahl() == 0))
  43. {
  44. bucketIndex++;
  45. iterator = Iterator< MapEntry<K, V> >(0, 0);
  46. }
  47. if (bucketIndex < bucketCount)
  48. {
  49. if (!iterator)
  50. this->iterator = buckets[bucketIndex]->begin();
  51. }
  52. else
  53. {
  54. this->iterator = Iterator< MapEntry<K, V> >(0, 0);
  55. this->bucketIndex = 0;
  56. this->buckets = 0;
  57. this->bucketCount = 0;
  58. return;
  59. }
  60. this->buckets = buckets;
  61. this->bucketCount = bucketCount;
  62. this->bucketIndex = bucketIndex;
  63. }
  64. MapIterator(const MapIterator< K, V >& it)
  65. : iterator(it.iterator)
  66. {
  67. buckets = it.buckets;
  68. bucketCount = it.bucketCount;
  69. bucketIndex = it.bucketIndex;
  70. }
  71. MapIterator< K, V >& operator=(MapIterator< K, V > r)
  72. {
  73. iterator = r.iterator;
  74. buckets = r.buckets;
  75. bucketCount = r.bucketCount;
  76. bucketIndex = r.bucketIndex;
  77. return *this;
  78. }
  79. bool hasNext()
  80. {
  81. if (iterator && iterator.hasNext())
  82. return 1;
  83. int ind = bucketIndex + 1;
  84. while (ind < bucketCount && (!buckets[ind] || buckets[ind]->getEintragAnzahl() == 0))
  85. ind++;
  86. return ind < bucketCount;
  87. }
  88. MapIterator< K, V > next()
  89. {
  90. if (bucketIndex >= bucketCount)
  91. {
  92. Text err = "Index out of Range Exception File: ";
  93. err += __FILE__;
  94. err += " Line: ";
  95. err += __LINE__;
  96. throw std::out_of_range(err);
  97. }
  98. if (iterator.hasNext())
  99. return MapIterator(buckets, bucketCount, bucketIndex, iterator.next());
  100. else
  101. return MapIterator(buckets, bucketCount, bucketIndex + 1, Iterator< MapEntry<K, V> >(0, 0));
  102. }
  103. operator bool()
  104. {
  105. return bucketIndex < bucketCount;
  106. }
  107. operator MapEntry<K, V>()
  108. {
  109. if (bucketIndex >= bucketCount)
  110. {
  111. Text err = "Index out of Range Exception File: ";
  112. err += __FILE__;
  113. err += " Line: ";
  114. err += __LINE__;
  115. throw std::out_of_range(err);
  116. }
  117. return iterator.val();
  118. }
  119. MapIterator< K, V >& operator++() //! prefix
  120. {
  121. ++iterator;
  122. if (!iterator)
  123. {
  124. bucketIndex++;
  125. while (bucketIndex < bucketCount && (!buckets[bucketIndex] || buckets[bucketIndex]->getEintragAnzahl() == 0))
  126. bucketIndex++;
  127. if (bucketIndex < bucketCount)
  128. this->iterator = buckets[bucketIndex]->begin();
  129. else
  130. {
  131. this->iterator = Iterator< MapEntry<K, V> >(0, 0);
  132. this->bucketIndex = 0;
  133. this->buckets = 0;
  134. this->bucketCount = 0;
  135. }
  136. }
  137. return *this;
  138. }
  139. MapIterator< K, V > operator++(int) //! postfix
  140. {
  141. MapIterator< K, V > temp(*this);
  142. ++(*this);
  143. return temp;
  144. }
  145. MapEntry< K, V > operator*()
  146. {
  147. if (bucketIndex >= bucketCount)
  148. {
  149. Text err = "Index out of Range Exception File: ";
  150. err += __FILE__;
  151. err += " Line: ";
  152. err += __LINE__;
  153. throw std::out_of_range(err);
  154. }
  155. return iterator.val();
  156. }
  157. MapEntry< K, V > operator->()
  158. {
  159. if (bucketIndex >= bucketCount)
  160. {
  161. Text err = "Index out of Range Exception File: ";
  162. err += __FILE__;
  163. err += " Line: ";
  164. err += __LINE__;
  165. throw std::out_of_range(err);
  166. }
  167. return iterator.val();
  168. }
  169. void set(MapEntry<K, V> val)
  170. {
  171. if (bucketIndex < bucketCount)
  172. iterator.set(val);
  173. else
  174. {
  175. Text err = "Index out of Range Exception File: ";
  176. err += __FILE__;
  177. err += " Line: ";
  178. err += __LINE__;
  179. throw std::out_of_range(err);
  180. }
  181. }
  182. bool operator!=(MapIterator< K, V >& r)
  183. {
  184. return buckets != r.buckets || iterator != r.iterator;
  185. }
  186. };
  187. template<typename K, typename V>
  188. class HashMap : public virtual ReferenceCounter
  189. {
  190. private:
  191. Array< MapEntry<K, V> >** buckets;
  192. int bucketCount;
  193. std::function<int(K)> hash;
  194. int size;
  195. public:
  196. HashMap(int bucketCount, std::function<int(K)> hash)
  197. : ReferenceCounter(),
  198. buckets(new Array< MapEntry<K, V> >* [bucketCount]),
  199. bucketCount(bucketCount),
  200. hash(hash),
  201. size(0)
  202. {
  203. memset(buckets, 0, sizeof(Array< MapEntry<K, V> > *) * bucketCount);
  204. }
  205. ~HashMap()
  206. {
  207. for (int i = 0; i < bucketCount; i++)
  208. {
  209. if (buckets[i])
  210. buckets[i]->release();
  211. }
  212. delete[] buckets;
  213. }
  214. void put(K key, V value)
  215. {
  216. int index = abs(hash(key)) % bucketCount;
  217. if (!buckets[index])
  218. buckets[index] = new Array< MapEntry<K, V>>();
  219. for (auto iterator = buckets[index]->begin(); iterator; iterator++)
  220. {
  221. if (iterator._.getKey() == key)
  222. {
  223. iterator.set(MapEntry<K, V>(key, value));
  224. return;
  225. }
  226. }
  227. buckets[index]->add(MapEntry<K, V>(key, value));
  228. size++;
  229. }
  230. void remove(K key)
  231. {
  232. int index = abs(hash(key)) % bucketCount;
  233. if (!buckets[index])
  234. return;
  235. int listIndex = 0;
  236. for (auto bucket : *buckets[index])
  237. {
  238. if (bucket.getKey() == key)
  239. {
  240. buckets[index]->remove(listIndex);
  241. size--;
  242. return;
  243. }
  244. listIndex++;
  245. }
  246. }
  247. V get(K key) const
  248. {
  249. int index = abs(hash(key)) % bucketCount;
  250. if (!buckets[index])
  251. throw "element not found";
  252. for (auto iterator : *buckets[index])
  253. {
  254. if (iterator.getKey() == key)
  255. return iterator.getValue();
  256. }
  257. throw "element not found";
  258. }
  259. V safeGet(K key, V fallback) const
  260. {
  261. int index = abs(hash(key)) % bucketCount;
  262. if (!buckets[index])
  263. return fallback;
  264. for (auto bucket : *buckets[index])
  265. {
  266. if (bucket.getKey() == key)
  267. return bucket.getValue();
  268. }
  269. return fallback;
  270. }
  271. bool has(K key) const
  272. {
  273. int index = abs(hash(key)) % bucketCount;
  274. if (!buckets[index])
  275. return 0;
  276. for (auto bucket : *buckets[index])
  277. {
  278. if (bucket.getKey() == key)
  279. return 1;
  280. }
  281. return 0;
  282. }
  283. int getSize() const
  284. {
  285. return size;
  286. }
  287. void leeren()
  288. {
  289. for (int i = 0; i < bucketCount; i++)
  290. {
  291. if (buckets[i])
  292. buckets[i]->leeren();
  293. }
  294. }
  295. MapIterator<K, V> begin()
  296. {
  297. return MapIterator<K, V>(buckets, bucketCount, 0, Iterator< MapEntry<K, V> >(0, 0));
  298. }
  299. MapIterator<K, V> end()
  300. {
  301. return MapIterator<K, V>(0, 0, 0, Iterator< MapEntry<K, V> >(0, 0));
  302. }
  303. };
  304. }