Map.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "ListBase.h"
  25. #include "Pair.h"
  26. #include <new>
  27. // Based on http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_skip.aspx
  28. /// Map template class using a skip list
  29. template <class T, class U> class Map : public SkipListBase
  30. {
  31. public:
  32. /// Map key-value pair with const key
  33. class KeyValue
  34. {
  35. public:
  36. /// Construct with key
  37. KeyValue(const T& first) :
  38. first_(first)
  39. {
  40. }
  41. /// Construct with key and value
  42. KeyValue(const T& first, const U& second) :
  43. first_(first),
  44. second_(second)
  45. {
  46. }
  47. /// Test for equality with another pair
  48. bool operator == (const KeyValue& rhs) const { return (first_ == rhs.first_) && (second_ == rhs.second_); }
  49. /// Test for inequality with another pair
  50. bool operator != (const KeyValue& rhs) const { return (first_ != rhs.first_) || (second_ != rhs.second_); }
  51. const T first_;
  52. U second_;
  53. };
  54. /// Map node
  55. struct Node : public SkipListNodeBase
  56. {
  57. /// Key-value pair
  58. KeyValue pair_;
  59. /// Return next node on a specific height
  60. Node* GetNext(unsigned height) const
  61. {
  62. if (!height)
  63. return static_cast<Node*>(next_);
  64. else
  65. return static_cast<Node*>(levels_[height - 1]);
  66. }
  67. /// Return previous node
  68. Node* GetPrev() { return static_cast<Node*>(prev_); }
  69. };
  70. /// Map node iterator
  71. class Iterator : public ListIteratorBase
  72. {
  73. public:
  74. /// Construct
  75. explicit Iterator(Node* ptr) :
  76. ListIteratorBase(ptr)
  77. {
  78. }
  79. /// Preincrement the pointer
  80. Iterator& operator ++ () { GotoNext(); return *this; }
  81. /// Postincrement the pointer
  82. Iterator operator ++ (int) { Iterator it = *this; GotoNext(); return it; }
  83. /// Predecrement the pointer
  84. Iterator& operator -- () { GotoPrev(); return *this; }
  85. /// Postdecrement the pointer
  86. Iterator operator -- (int) { Iterator it = *this; GotoPrev(); return it; }
  87. /// Point to the pair
  88. KeyValue* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  89. /// Dereference the pair
  90. KeyValue& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  91. };
  92. /// Set node const iterator
  93. class ConstIterator : public ListIteratorBase
  94. {
  95. public:
  96. /// Construct
  97. explicit ConstIterator(Node* ptr) :
  98. ListIteratorBase(ptr)
  99. {
  100. }
  101. /// Construct from a non-const iterator
  102. ConstIterator(const Iterator& rhs) :
  103. ListIteratorBase(rhs.ptr_)
  104. {
  105. }
  106. /// Assign from a non-const iterator
  107. ConstIterator& operator = (const Iterator& rhs) { ptr_ = rhs.ptr_; return *this; }
  108. /// Preincrement the pointer
  109. ConstIterator& operator ++ () { GotoNext(); return *this; }
  110. /// Postincrement the pointer
  111. ConstIterator operator ++ (int) { Iterator it = *this; GotoNext(); return it; }
  112. /// Predecrement the pointer
  113. ConstIterator& operator -- () { GotoPrev(); return *this; }
  114. /// Postdecrement the pointer
  115. ConstIterator operator -- (int) { Iterator it = *this; GotoPrev(); return it; }
  116. /// Point to the pair
  117. const KeyValue* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  118. /// Dereference the pair
  119. const KeyValue& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  120. };
  121. /// Construct empty
  122. Map(unsigned maxHeight = MAX_HEIGHT) :
  123. SkipListBase(maxHeight)
  124. {
  125. // Allocate the head and tail nodes and zero the next pointers
  126. head_ = AllocateNode(maxHeight_);
  127. tail_ = AllocateNode(maxHeight_);
  128. Node* head = GetHead();
  129. Node* tail = GetTail();
  130. for (unsigned i = 0; i < maxHeight_; ++i)
  131. {
  132. head->SetNext(i, tail);
  133. tail->SetNext(i, 0);
  134. }
  135. // Allocate the fixup pointers
  136. fix_ = reinterpret_cast<void**>(new Node*[maxHeight_]);
  137. }
  138. /// Construct from another map
  139. Map(const Map<T, U>& map) :
  140. SkipListBase(map.maxHeight_)
  141. {
  142. // Allocate the head and tail nodes and zero the next pointers
  143. head_ = AllocateNode(maxHeight_);
  144. tail_ = AllocateNode(maxHeight_);
  145. Node* head = GetHead();
  146. Node* tail = GetTail();
  147. for (unsigned i = 0; i < maxHeight_; ++i)
  148. {
  149. head->SetNext(i, tail);
  150. tail->SetNext(i, 0);
  151. }
  152. // Allocate the fixup pointers
  153. fix_ = reinterpret_cast<void**>(new Node*[maxHeight_]);
  154. // Then assign the other map
  155. *this = map;
  156. }
  157. /// Destruct
  158. ~Map()
  159. {
  160. Clear();
  161. DeleteNode(GetHead());
  162. DeleteNode(GetTail());
  163. delete[] GetFix();
  164. }
  165. /// Assign from another map
  166. Map& operator = (const Map<T, U>& rhs)
  167. {
  168. Clear();
  169. // Insert the nodes with same heights
  170. for (Node* i = rhs.GetHead()->GetNext(0); i != rhs.GetTail(); i = i->GetNext(0))
  171. InsertNode(Pair<T, U>(i->pair_.first_, i->pair_.second_), i->height_);
  172. return *this;
  173. }
  174. /// Add-assign a pair
  175. Map& operator += (const Pair<T, U>& rhs)
  176. {
  177. Insert(rhs);
  178. return *this;
  179. }
  180. /// Add-assign a map
  181. Map& operator += (const Map<T, U>& rhs)
  182. {
  183. Insert(rhs.Begin(), rhs.End());
  184. return *this;
  185. }
  186. /// Index the map
  187. U& operator [] (const T& key)
  188. {
  189. Node* node = FindNode(key);
  190. if (node)
  191. return node->pair_.second_;
  192. else
  193. {
  194. // If node did not exist, insert a node with default value, then return the value
  195. node = InsertNode(Pair<T, U>(key, U()), 0);
  196. return node->pair_.second_;
  197. }
  198. }
  199. /// Test for equality with another map
  200. bool operator == (const Map<T, U>& rhs) const
  201. {
  202. if (rhs.size_ != size_)
  203. return false;
  204. ConstIterator i = Begin();
  205. ConstIterator j = rhs.Begin();
  206. while (i != End())
  207. {
  208. if (*i != *j)
  209. return false;
  210. ++i;
  211. ++j;
  212. }
  213. return true;
  214. }
  215. /// Test for inequality with another map
  216. bool operator != (const Map<T, U>& rhs) const
  217. {
  218. if (rhs.size_ != size_)
  219. return true;
  220. ConstIterator i = Begin();
  221. ConstIterator j = rhs.Begin();
  222. while (i != End())
  223. {
  224. if (*i != *j)
  225. return true;
  226. ++i;
  227. ++j;
  228. }
  229. return false;
  230. }
  231. /// Insert into the map
  232. void Insert(const T& key, const U& value)
  233. {
  234. InsertNode(MakePair(key, value), 0);
  235. }
  236. /// Insert into the map
  237. void Insert(const Pair<T, U>& pair)
  238. {
  239. InsertNode(pair, 0);
  240. }
  241. /// Insert a range by iterators
  242. void Insert(const Iterator& start, const Iterator& end)
  243. {
  244. Iterator it = start;
  245. while (it != end)
  246. {
  247. Iterator current = it++;
  248. Insert(*current);
  249. // Break if the iterator got stuck
  250. if (it == current)
  251. break;
  252. }
  253. }
  254. /// Erase a key from the map. Return true if was found and erased
  255. bool Erase(const T& key)
  256. {
  257. Node* head = GetHead();
  258. Node* tail = GetTail();
  259. Node** fix = GetFix();
  260. Node* i = head;
  261. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  262. {
  263. for (;;)
  264. {
  265. Node* next = i->GetNext(j);
  266. if ((next) && (next != tail) && (key > next->pair_.first_))
  267. i = next;
  268. else
  269. break;
  270. }
  271. fix_[j] = i;
  272. }
  273. // Check if key does not exist
  274. Node* toRemove = i->GetNext(0);
  275. if ((!toRemove) || (toRemove == tail) || (toRemove->pair_.first_ != key))
  276. return false;
  277. // Fix the previous link. However, do not set the head node as a previous link
  278. Node* prev = toRemove->GetPrev();
  279. Node* next = toRemove->GetNext(0);
  280. if (next)
  281. next->SetPrev(prev != head ? prev : 0);
  282. // Fix the next links
  283. for (unsigned j = 0; j < height_; ++j)
  284. {
  285. Node* fixNext = fix[j]->GetNext(j);
  286. if (fixNext)
  287. fix[j]->SetNext(j, fixNext->GetNext(j));
  288. }
  289. // Check if height should be changed
  290. while (height_ > 0)
  291. {
  292. if (head->GetNext(height_ - 1))
  293. break;
  294. head->SetNext(--height_, 0);
  295. }
  296. DeleteNode(toRemove);
  297. --size_;
  298. return true;
  299. }
  300. /// Erase by an iterator. Return an iterator to the next element
  301. Iterator Erase(Iterator it)
  302. {
  303. if (it != End())
  304. {
  305. Iterator current = it++;
  306. Erase(current->first_);
  307. }
  308. return it;
  309. }
  310. /// Erase by a range of iterators. Return the end iterator
  311. Iterator Erase(const Iterator& start, const Iterator& end)
  312. {
  313. Iterator it = start;
  314. while (it != end)
  315. {
  316. Iterator current = it++;
  317. // Break if the iterator got stuck
  318. if (it == current)
  319. break;
  320. Erase(current->first_);
  321. }
  322. return it;
  323. }
  324. /// Clear the map
  325. void Clear()
  326. {
  327. // Let the head and tails node remain, but reset the next pointers
  328. Node* head = GetHead();
  329. Node* tail = GetTail();
  330. Node* node = head->GetNext(0);
  331. for (unsigned i = 0; i < maxHeight_; ++i)
  332. {
  333. head->SetNext(i, tail);
  334. tail->SetPrev(0);
  335. }
  336. // Then remove all the key nodes
  337. while (node != tail_)
  338. {
  339. Node* current = node;
  340. node = node->GetNext(0);
  341. DeleteNode(current);
  342. }
  343. height_ = 0;
  344. size_ = 0;
  345. }
  346. /// Return iterator to the node with key, or end iterator if not found
  347. Iterator Find(const T& key) { Node* node = FindNode(key); return node ? Iterator(node) : End(); }
  348. /// Return const iterator to the node with key, or null iterator if not found
  349. ConstIterator Find(const T& key) const { Node* node = FindNode(key); return node ? ConstIterator(node) : End(); }
  350. /// Return iterator to the first actual node
  351. Iterator Begin() { return Iterator(GetHead()->GetNext(0)); }
  352. /// Return iterator to the first actual node
  353. ConstIterator Begin() const { return ConstIterator(GetHead()->GetNext(0)); }
  354. /// Return iterator to the end
  355. Iterator End() { return Iterator(GetTail()); }
  356. /// Return iterator to the end
  357. ConstIterator End() const { return ConstIterator(GetTail()); }
  358. /// Return first pair
  359. KeyValue& Front() { return *Begin(); }
  360. /// Return const first pair
  361. const KeyValue& Front() const { return *Begin(); }
  362. /// Return last pair
  363. const KeyValue& Back() { return *(--End()); }
  364. /// Return const last pair
  365. const KeyValue& Back() const { return *(--End()); }
  366. /// Return whether contains a key
  367. bool Contains(const T& key) const { return FindNode(key) != 0; }
  368. /// Return number of keys
  369. unsigned Size() const { return size_; }
  370. /// Return current height
  371. unsigned Height() const { return height_; }
  372. /// Return whether map is empty
  373. bool Empty() const { return size_ == 0; }
  374. private:
  375. /// Return the head pointer with correct type
  376. Node* GetHead() const { return reinterpret_cast<Node*>(head_); }
  377. /// Return the tail pointer with correct type
  378. Node* GetTail() const { return reinterpret_cast<Node*>(tail_); }
  379. /// Return the fixup array with correct type
  380. Node** GetFix() const { return reinterpret_cast<Node**>(fix_); }
  381. /// Find a key from the map. Return null if not found
  382. Node* FindNode(const T& key) const
  383. {
  384. Node* i = GetHead();
  385. Node* tail = GetTail();
  386. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  387. {
  388. for (;;)
  389. {
  390. Node* next = i->GetNext(j);
  391. if ((next) && (next != tail) && (key > next->pair_.first_))
  392. i = next;
  393. else
  394. break;
  395. }
  396. }
  397. Node* next = i->GetNext(0);
  398. if ((next) && (next != tail) && (next->pair_.first_ == key))
  399. return next;
  400. else
  401. return 0;
  402. }
  403. /// Insert into the map with a specific height. Zero height will randomize. Return the node
  404. Node* InsertNode(const Pair<T, U>& pair, unsigned height)
  405. {
  406. Node* head = GetHead();
  407. Node* tail = GetTail();
  408. Node** fix = GetFix();
  409. Node* i = head;
  410. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  411. {
  412. for (;;)
  413. {
  414. Node* next = i->GetNext(j);
  415. if ((next) && (next != tail) && (pair.first_ > next->pair_.first_))
  416. i = next;
  417. else
  418. break;
  419. }
  420. fix[j] = i;
  421. }
  422. // Check if key already exists, in that case only modify the value
  423. Node* next = i->GetNext(0);
  424. if ((next) && (next != tail) && (next->pair_.first_ == pair.first_))
  425. {
  426. next->pair_.second_ = pair.second_;
  427. return next;
  428. }
  429. // Create new node, assign height and key
  430. if (!height)
  431. height = GetHeight();
  432. Node* newNode = AllocateNode(height, pair.first_);
  433. newNode->pair_.second_ = pair.second_;
  434. // Fix the previous link, however do not set the head node as previous
  435. if (i != head)
  436. newNode->SetPrev(i);
  437. if (next)
  438. next->SetPrev(newNode);
  439. while (newNode->height_ > height_)
  440. fix[height_++] = head;
  441. for (unsigned h = 0; h < newNode->height_; ++h)
  442. {
  443. newNode->SetNext(h, fix[h]->GetNext(h));
  444. fix[h]->SetNext(h, newNode);
  445. }
  446. ++size_;
  447. return newNode;
  448. }
  449. /// Allocate a node and its next pointers
  450. Node* AllocateNode(unsigned height, const T& key = T())
  451. {
  452. unsigned char* block = new unsigned char[sizeof(Node) + (height - 1) * sizeof(Node*)];
  453. Node* newNode = reinterpret_cast<Node*>(block);
  454. // Construct the pair with placement new and map the next pointers' address
  455. new(&newNode->pair_) KeyValue(key);
  456. newNode->height_ = height;
  457. if (height > 1)
  458. newNode->levels_ = reinterpret_cast<SkipListNodeBase**>(block + sizeof(Node));
  459. else
  460. newNode->levels_ = 0;
  461. return newNode;
  462. }
  463. /// Delete a node
  464. void DeleteNode(Node* node)
  465. {
  466. // Destruct the pair, then delete the memory block
  467. (&node->pair_)->~KeyValue();
  468. delete[] reinterpret_cast<unsigned char*>(node);
  469. }
  470. };