HashMap.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashBase.h"
  24. #include "../Container/Pair.h"
  25. #include "../Container/Sort.h"
  26. #include "../Container/Vector.h"
  27. #include <cassert>
  28. namespace Atomic
  29. {
  30. /// Hash map template class.
  31. template <class T, class U> class HashMap : public HashBase
  32. {
  33. public:
  34. typedef T KeyType;
  35. typedef U ValueType;
  36. /// Hash map key-value pair with const key.
  37. class KeyValue
  38. {
  39. public:
  40. /// Construct with default key.
  41. KeyValue() :
  42. first_(T())
  43. {
  44. }
  45. /// Construct with key and value.
  46. KeyValue(const T& first, const U& second) :
  47. first_(first),
  48. second_(second)
  49. {
  50. }
  51. /// Copy-construct.
  52. KeyValue(const KeyValue& value) :
  53. first_(value.first_),
  54. second_(value.second_)
  55. {
  56. }
  57. /// Test for equality with another pair.
  58. bool operator == (const KeyValue& rhs) const { return first_ == rhs.first_ && second_ == rhs.second_; }
  59. /// Test for inequality with another pair.
  60. bool operator != (const KeyValue& rhs) const { return first_ != rhs.first_ || second_ != rhs.second_; }
  61. /// Key.
  62. const T first_;
  63. /// Value.
  64. U second_;
  65. private:
  66. /// Prevent assignment.
  67. KeyValue& operator = (const KeyValue& rhs);
  68. };
  69. /// Hash map node.
  70. struct Node : public HashNodeBase
  71. {
  72. /// Construct undefined.
  73. Node()
  74. {
  75. }
  76. /// Construct with key and value.
  77. Node(const T& key, const U& value) :
  78. pair_(key, value)
  79. {
  80. }
  81. /// Key-value pair.
  82. KeyValue pair_;
  83. /// Return next node.
  84. Node* Next() const { return static_cast<Node*>(next_); }
  85. /// Return previous node.
  86. Node* Prev() const { return static_cast<Node*>(prev_); }
  87. /// Return next node in the bucket.
  88. Node* Down() const { return static_cast<Node*>(down_); }
  89. };
  90. /// Hash map node iterator.
  91. struct Iterator : public HashIteratorBase
  92. {
  93. /// Construct.
  94. Iterator()
  95. {
  96. }
  97. /// Construct with a node pointer.
  98. Iterator(Node* ptr) :
  99. HashIteratorBase(ptr)
  100. {
  101. }
  102. /// Preincrement the pointer.
  103. Iterator& operator ++ () { GotoNext(); return *this; }
  104. /// Postincrement the pointer.
  105. Iterator operator ++ (int) { Iterator it = *this; GotoNext(); return it; }
  106. /// Predecrement the pointer.
  107. Iterator& operator -- () { GotoPrev(); return *this; }
  108. /// Postdecrement the pointer.
  109. Iterator operator -- (int) { Iterator it = *this; GotoPrev(); return it; }
  110. /// Point to the pair.
  111. KeyValue* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  112. /// Dereference the pair.
  113. KeyValue& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  114. };
  115. /// Hash map node const iterator.
  116. struct ConstIterator : public HashIteratorBase
  117. {
  118. /// Construct.
  119. ConstIterator()
  120. {
  121. }
  122. /// Construct with a node pointer.
  123. ConstIterator(Node* ptr) :
  124. HashIteratorBase(ptr)
  125. {
  126. }
  127. /// Construct from a non-const iterator.
  128. ConstIterator(const Iterator& rhs) :
  129. HashIteratorBase(rhs.ptr_)
  130. {
  131. }
  132. /// Assign from a non-const iterator.
  133. ConstIterator& operator = (const Iterator& rhs) { ptr_ = rhs.ptr_; return *this; }
  134. /// Preincrement the pointer.
  135. ConstIterator& operator ++ () { GotoNext(); return *this; }
  136. /// Postincrement the pointer.
  137. ConstIterator operator ++ (int) { ConstIterator it = *this; GotoNext(); return it; }
  138. /// Predecrement the pointer.
  139. ConstIterator& operator -- () { GotoPrev(); return *this; }
  140. /// Postdecrement the pointer.
  141. ConstIterator operator -- (int) { ConstIterator it = *this; GotoPrev(); return it; }
  142. /// Point to the pair.
  143. const KeyValue* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  144. /// Dereference the pair.
  145. const KeyValue& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  146. };
  147. /// Construct empty.
  148. HashMap()
  149. {
  150. // Reserve the tail node
  151. allocator_ = AllocatorInitialize(sizeof(Node));
  152. head_ = tail_ = ReserveNode();
  153. }
  154. /// Construct from another hash map.
  155. HashMap(const HashMap<T, U>& map)
  156. {
  157. // Reserve the tail node + initial capacity according to the map's size
  158. allocator_ = AllocatorInitialize(sizeof(Node), map.Size() + 1);
  159. head_ = tail_ = ReserveNode();
  160. *this = map;
  161. }
  162. /// Destruct.
  163. ~HashMap()
  164. {
  165. Clear();
  166. FreeNode(Tail());
  167. AllocatorUninitialize(allocator_);
  168. delete[] ptrs_;
  169. }
  170. /// Assign a hash map.
  171. HashMap& operator = (const HashMap<T, U>& rhs)
  172. {
  173. Clear();
  174. Insert(rhs);
  175. return *this;
  176. }
  177. /// Add-assign a pair.
  178. HashMap& operator += (const Pair<T, U>& rhs)
  179. {
  180. Insert(rhs);
  181. return *this;
  182. }
  183. /// Add-assign a hash map.
  184. HashMap& operator += (const HashMap<T, U>& rhs)
  185. {
  186. Insert(rhs);
  187. return *this;
  188. }
  189. /// Test for equality with another hash map.
  190. bool operator == (const HashMap<T, U>& rhs) const
  191. {
  192. if (rhs.Size() != Size())
  193. return false;
  194. ConstIterator i = Begin();
  195. while (i != End())
  196. {
  197. ConstIterator j = rhs.Find(i->first_);
  198. if (j == rhs.End() || j->second_ != i->second_)
  199. return false;
  200. ++i;
  201. }
  202. return true;
  203. }
  204. /// Test for inequality with another hash map.
  205. bool operator != (const HashMap<T, U>& rhs) const
  206. {
  207. if (rhs.Size() != Size())
  208. return true;
  209. ConstIterator i = Begin();
  210. while (i != End())
  211. {
  212. ConstIterator j = rhs.Find(i->first_);
  213. if (j == rhs.End() || j->second_ != i->second_)
  214. return true;
  215. ++i;
  216. }
  217. return false;
  218. }
  219. /// Index the map. Create a new pair if key not found.
  220. U& operator [] (const T& key)
  221. {
  222. if (!ptrs_)
  223. return InsertNode(key, U(), false)->pair_.second_;
  224. unsigned hashKey = Hash(key);
  225. Node* node = FindNode(key, hashKey);
  226. if (node)
  227. return node->pair_.second_;
  228. else
  229. return InsertNode(key, U(), false)->pair_.second_;
  230. }
  231. /// Insert a pair. Return an iterator to it.
  232. Iterator Insert(const Pair<T, U>& pair)
  233. {
  234. return Iterator(InsertNode(pair.first_, pair.second_));
  235. }
  236. /// Insert a map.
  237. void Insert(const HashMap<T, U>& map)
  238. {
  239. ConstIterator it = map.Begin();
  240. ConstIterator end = map.End();
  241. while (it != end)
  242. {
  243. InsertNode(it->first_, it->second_);
  244. ++it;
  245. }
  246. }
  247. /// Insert a pair by iterator. Return iterator to the value.
  248. Iterator Insert(const ConstIterator& it) { return Iterator(InsertNode(it->first_, it->second_)); }
  249. /// Insert a range by iterators.
  250. void Insert(const ConstIterator& start, const ConstIterator& end)
  251. {
  252. ConstIterator it = start;
  253. while (it != end)
  254. InsertNode(*it++);
  255. }
  256. /// Erase a pair by key. Return true if was found.
  257. bool Erase(const T& key)
  258. {
  259. if (!ptrs_)
  260. return false;
  261. unsigned hashKey = Hash(key);
  262. Node* previous;
  263. Node* node = FindNode(key, hashKey, previous);
  264. if (!node)
  265. return false;
  266. if (previous)
  267. previous->down_ = node->down_;
  268. else
  269. Ptrs()[hashKey] = node->down_;
  270. EraseNode(node);
  271. return true;
  272. }
  273. /// Erase a pair by iterator. Return iterator to the next pair.
  274. Iterator Erase(const Iterator& it)
  275. {
  276. if (!ptrs_ || !it.ptr_)
  277. return End();
  278. Node* node = static_cast<Node*>(it.ptr_);
  279. Node* next = node->Next();
  280. unsigned hashKey = Hash(node->pair_.first_);
  281. Node* previous = 0;
  282. Node* current = static_cast<Node*>(Ptrs()[hashKey]);
  283. while (current && current != node)
  284. {
  285. previous = current;
  286. current = current->Down();
  287. }
  288. assert(current == node);
  289. if (previous)
  290. previous->down_ = node->down_;
  291. else
  292. Ptrs()[hashKey] = node->down_;
  293. EraseNode(node);
  294. return Iterator(next);
  295. }
  296. /// Clear the map.
  297. void Clear()
  298. {
  299. if (Size())
  300. {
  301. for (Iterator i = Begin(); i != End(); )
  302. {
  303. FreeNode(static_cast<Node*>(i++.ptr_));
  304. i.ptr_->prev_ = 0;
  305. }
  306. head_ = tail_;
  307. SetSize(0);
  308. }
  309. ResetPtrs();
  310. }
  311. /// Sort pairs. After sorting the map can be iterated in order until new elements are inserted.
  312. void Sort()
  313. {
  314. unsigned numKeys = Size();
  315. if (!numKeys)
  316. return;
  317. Node** ptrs = new Node*[numKeys];
  318. Node* ptr = Head();
  319. for (unsigned i = 0; i < numKeys; ++i)
  320. {
  321. ptrs[i] = ptr;
  322. ptr = ptr->Next();
  323. }
  324. Atomic::Sort(RandomAccessIterator<Node*>(ptrs), RandomAccessIterator<Node*>(ptrs + numKeys), CompareNodes);
  325. head_ = ptrs[0];
  326. ptrs[0]->prev_ = 0;
  327. for (unsigned i = 1; i < numKeys; ++i)
  328. {
  329. ptrs[i - 1]->next_ = ptrs[i];
  330. ptrs[i]->prev_ = ptrs[i - 1];
  331. }
  332. ptrs[numKeys - 1]->next_ = tail_;
  333. tail_->prev_ = ptrs[numKeys - 1];
  334. delete[] ptrs;
  335. }
  336. /// Rehash to a specific bucket count, which must be a power of two. Return true if successful.
  337. bool Rehash(unsigned numBuckets)
  338. {
  339. if (numBuckets == NumBuckets())
  340. return true;
  341. if (!numBuckets || numBuckets < Size() / MAX_LOAD_FACTOR)
  342. return false;
  343. // Check for being power of two
  344. unsigned check = numBuckets;
  345. while (!(check & 1))
  346. check >>= 1;
  347. if (check != 1)
  348. return false;
  349. AllocateBuckets(Size(), numBuckets);
  350. Rehash();
  351. return true;
  352. }
  353. /// Return iterator to the pair with key, or end iterator if not found.
  354. Iterator Find(const T& key)
  355. {
  356. if (!ptrs_)
  357. return End();
  358. unsigned hashKey = Hash(key);
  359. Node* node = FindNode(key, hashKey);
  360. if (node)
  361. return Iterator(node);
  362. else
  363. return End();
  364. }
  365. /// Return const iterator to the pair with key, or end iterator if not found.
  366. ConstIterator Find(const T& key) const
  367. {
  368. if (!ptrs_)
  369. return End();
  370. unsigned hashKey = Hash(key);
  371. Node* node = FindNode(key, hashKey);
  372. if (node)
  373. return ConstIterator(node);
  374. else
  375. return End();
  376. }
  377. /// Return whether contains a pair with key.
  378. bool Contains(const T& key) const
  379. {
  380. if (!ptrs_)
  381. return false;
  382. unsigned hashKey = Hash(key);
  383. return FindNode(key, hashKey) != 0;
  384. }
  385. /// Return all the keys.
  386. Vector<T> Keys() const
  387. {
  388. Vector<T> result;
  389. result.Reserve(Size());
  390. for (ConstIterator i = Begin(); i != End(); ++i)
  391. result.Push(i->first_);
  392. return result;
  393. }
  394. /// Return all the values.
  395. Vector<U> Values() const
  396. {
  397. Vector<U> result;
  398. result.Reserve(Size());
  399. for (ConstIterator i = Begin(); i != End(); ++i)
  400. result.Push(i->second_);
  401. return result;
  402. }
  403. /// Return iterator to the beginning.
  404. Iterator Begin() { return Iterator(Head()); }
  405. /// Return iterator to the beginning.
  406. ConstIterator Begin() const { return ConstIterator(Head()); }
  407. /// Return iterator to the end.
  408. Iterator End() { return Iterator(Tail()); }
  409. /// Return iterator to the end.
  410. ConstIterator End() const { return ConstIterator(Tail()); }
  411. /// Return first key.
  412. const T& Front() const { return *Begin(); }
  413. /// Return last key.
  414. const T& Back() const { return *(--End()); }
  415. private:
  416. /// Return the head node.
  417. Node* Head() const { return static_cast<Node*>(head_); }
  418. /// Return the tail node.
  419. Node* Tail() const { return static_cast<Node*>(tail_); }
  420. /// Find a node from the buckets. Do not call if the buckets have not been allocated.
  421. Node* FindNode(const T& key, unsigned hashKey) const
  422. {
  423. Node* node = static_cast<Node*>(Ptrs()[hashKey]);
  424. while (node)
  425. {
  426. if (node->pair_.first_ == key)
  427. return node;
  428. node = node->Down();
  429. }
  430. return 0;
  431. }
  432. /// Find a node and the previous node from the buckets. Do not call if the buckets have not been allocated.
  433. Node* FindNode(const T& key, unsigned hashKey, Node*& previous) const
  434. {
  435. previous = 0;
  436. Node* node = static_cast<Node*>(Ptrs()[hashKey]);
  437. while (node)
  438. {
  439. if (node->pair_.first_ == key)
  440. return node;
  441. previous = node;
  442. node = node->Down();
  443. }
  444. return 0;
  445. }
  446. /// Insert a key and value and return either the new or existing node.
  447. Node* InsertNode(const T& key, const U& value, bool findExisting = true)
  448. {
  449. // If no pointers yet, allocate with minimum bucket count
  450. if (!ptrs_)
  451. {
  452. AllocateBuckets(Size(), MIN_BUCKETS);
  453. Rehash();
  454. }
  455. unsigned hashKey = Hash(key);
  456. if (findExisting)
  457. {
  458. // If exists, just change the value
  459. Node* existing = FindNode(key, hashKey);
  460. if (existing)
  461. {
  462. existing->pair_.second_ = value;
  463. return existing;
  464. }
  465. }
  466. Node* newNode = InsertNode(Tail(), key, value);
  467. newNode->down_ = Ptrs()[hashKey];
  468. Ptrs()[hashKey] = newNode;
  469. // Rehash if the maximum load factor has been exceeded
  470. if (Size() > NumBuckets() * MAX_LOAD_FACTOR)
  471. {
  472. AllocateBuckets(Size(), NumBuckets() << 1);
  473. Rehash();
  474. }
  475. return newNode;
  476. }
  477. /// Insert a node into the list. Return the new node.
  478. Node* InsertNode(Node* dest, const T& key, const U& value)
  479. {
  480. if (!dest)
  481. return 0;
  482. Node* newNode = ReserveNode(key, value);
  483. Node* prev = dest->Prev();
  484. newNode->next_ = dest;
  485. newNode->prev_ = prev;
  486. if (prev)
  487. prev->next_ = newNode;
  488. dest->prev_ = newNode;
  489. // Reassign the head node if necessary
  490. if (dest == Head())
  491. head_ = newNode;
  492. SetSize(Size() + 1);
  493. return newNode;
  494. }
  495. /// Erase a node from the list. Return pointer to the next element, or to the end if could not erase.
  496. Node* EraseNode(Node* node)
  497. {
  498. // The tail node can not be removed
  499. if (!node || node == tail_)
  500. return Tail();
  501. Node* prev = node->Prev();
  502. Node* next = node->Next();
  503. if (prev)
  504. prev->next_ = next;
  505. next->prev_ = prev;
  506. // Reassign the head node if necessary
  507. if (node == Head())
  508. head_ = next;
  509. FreeNode(node);
  510. SetSize(Size() - 1);
  511. return next;
  512. }
  513. /// Reserve a node.
  514. Node* ReserveNode()
  515. {
  516. Node* newNode = static_cast<Node*>(AllocatorReserve(allocator_));
  517. new(newNode) Node();
  518. return newNode;
  519. }
  520. /// Reserve a node with specified key and value.
  521. Node* ReserveNode(const T& key, const U& value)
  522. {
  523. Node* newNode = static_cast<Node*>(AllocatorReserve(allocator_));
  524. new(newNode) Node(key, value);
  525. return newNode;
  526. }
  527. /// Free a node.
  528. void FreeNode(Node* node)
  529. {
  530. (node)->~Node();
  531. AllocatorFree(allocator_, node);
  532. }
  533. /// Rehash the buckets.
  534. void Rehash()
  535. {
  536. for (Iterator i = Begin(); i != End(); ++i)
  537. {
  538. Node* node = static_cast<Node*>(i.ptr_);
  539. unsigned hashKey = Hash(i->first_);
  540. node->down_ = Ptrs()[hashKey];
  541. Ptrs()[hashKey] = node;
  542. }
  543. }
  544. /// Compare two nodes.
  545. static bool CompareNodes(Node*& lhs, Node*& rhs) { return lhs->pair_.first_ < rhs->pair_.first_; }
  546. /// Compute a hash based on the key and the bucket size
  547. unsigned Hash(const T& key) const { return MakeHash(key) & (NumBuckets() - 1); }
  548. };
  549. }