Map.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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 "Pair.h"
  25. #include <cstdlib>
  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
  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 Pair<T, U>& rhs) { return (first_ == rhs.first_) && (second_ == rhs.second_); }
  49. /// Test for inequality with another pair
  50. bool operator != (const Pair<T, U>& rhs) { 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. explicit Iterator(Node* ptr) :
  75. ptr_(ptr)
  76. {
  77. }
  78. /// Point to the pair
  79. T* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  80. /// Dereference the pair
  81. T& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  82. };
  83. /// Map node const iterator
  84. class ConstIterator : public ListIteratorBase
  85. {
  86. public:
  87. explicit ConstIterator(Node* ptr) :
  88. ptr_(ptr)
  89. {
  90. }
  91. /// Point to the pair
  92. const T* operator -> () const { return &(static_cast<Node*>(ptr_))->pair_; }
  93. /// Dereference the pair
  94. const T& operator * () const { return (static_cast<Node*>(ptr_))->pair_; }
  95. };
  96. /// Construct empty
  97. Map(unsigned maxHeight = MAX_HEIGHT) :
  98. maxHeight_(maxHeight < MAX_HEIGHT ? maxHeight : MAX_HEIGHT),
  99. height_(0),
  100. size_(0),
  101. bitsLeft_(0)
  102. {
  103. // Allocate the head and tail nodes and zero the next pointers
  104. head_ = AllocateNode(maxHeight_, T());
  105. tail_ = AllocateNode(maxHeight_, T());
  106. for (unsigned i = 0; i < maxHeight_; ++i)
  107. {
  108. head_->SetNext(i, tail_);
  109. tail_->SetNext(i, 0);
  110. }
  111. // Allocate the fixup pointers
  112. fix_ = new Node*[maxHeight_];
  113. }
  114. /// Construct from another map
  115. Map(const Map<T, U>& map) :
  116. maxHeight_(map.maxHeight_),
  117. height_(0),
  118. size_(0),
  119. bitsLeft_(0)
  120. {
  121. // Allocate the head and tail nodes and zero the next pointers
  122. head_ = AllocateNode(maxHeight_, T());
  123. tail_ = AllocateNode(maxHeight_, T());
  124. for (unsigned i = 0; i < maxHeight_; ++i)
  125. {
  126. head_->SetNext(i, tail_);
  127. tail_->SetNext(i, 0);
  128. }
  129. // Allocate the fixup pointers
  130. fix_ = new Node*[maxHeight_];
  131. // Then assign the another map
  132. *this = map;
  133. }
  134. /// Destruct
  135. ~Map()
  136. {
  137. Clear();
  138. DeleteNode(head_);
  139. DeleteNode(tail_);
  140. delete[] fix_;
  141. }
  142. /// Assign from another map
  143. Map& operator = (const Map<T, U>& rhs)
  144. {
  145. Clear();
  146. // Insert the nodes with same heights
  147. for (Node* i = rhs.head_->next_[0]; i; i = i->next_[0])
  148. InsertNode(i->pair_, i->height_);
  149. return *this;
  150. }
  151. /// Add-assign a pair
  152. Map& operator += (const Pair<T, U>& rhs)
  153. {
  154. Insert(rhs);
  155. return *this;
  156. }
  157. /// Add-assign a map
  158. Map& operator += (const Map<T, U>& rhs)
  159. {
  160. for (Iterator i = rhs.Begin(); i != rhs.End(); ++i)
  161. Insert(*i);
  162. return *this;
  163. }
  164. /// Index the map
  165. U& operator [] (const T& key)
  166. {
  167. Node* node = FindNode(key);
  168. if (node)
  169. return node->pair_.second_;
  170. else
  171. {
  172. // If node did not exist, insert a node with default value, then return the value
  173. node = InsertNode(Pair<T, U>(key, U()), 0);
  174. return node->pair_.second_;
  175. }
  176. }
  177. /// Test for equality with another map
  178. bool operator == (const Map<T, U>& rhs) const
  179. {
  180. if (rhs.size_ != size_)
  181. return false;
  182. ConstIterator i = Begin();
  183. ConstIterator j = rhs.Begin();
  184. while (i != End())
  185. {
  186. if (*i != *j)
  187. return false;
  188. ++i;
  189. ++j;
  190. }
  191. return true;
  192. }
  193. /// Test for inequality with another map
  194. bool operator != (const Map<T, U>& rhs) const
  195. {
  196. if (rhs.size_ != size_)
  197. return true;
  198. ConstIterator i = Begin();
  199. ConstIterator j = rhs.Begin();
  200. while (i != End())
  201. {
  202. if (*i != *j)
  203. return true;
  204. ++i;
  205. ++j;
  206. }
  207. return false;
  208. }
  209. /// Insert into the map
  210. void Insert(const T& key, const U& value)
  211. {
  212. InsertNode(MakePair(key, value), 0);
  213. }
  214. /// Insert into the map
  215. void Insert(const Pair<T, U>& pair)
  216. {
  217. InsertNode(pair, 0);
  218. }
  219. /// Insert a range by iterators
  220. void Insert(const Iterator& start, const Iterator& end)
  221. {
  222. Iterator it = start;
  223. while (it != end)
  224. {
  225. Iterator current = it++;
  226. Insert(*current);
  227. // Break if the iterator got stuck
  228. if (it == current)
  229. break;
  230. }
  231. }
  232. /// Erase a key from the map. Return true if was found and erased
  233. bool Erase(const T& key)
  234. {
  235. Node* i = head_;
  236. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  237. {
  238. for (;;)
  239. {
  240. Node* next = i->GetNext(j);
  241. if ((next) && (next != tail_) && (key > next->pair_.first_))
  242. i = next;
  243. else
  244. break;
  245. }
  246. fix_[j] = i;
  247. }
  248. // Check if key does not exist
  249. Node* toRemove = i->GetNext(0);
  250. if ((!toRemove) || (toRemove == tail_) || (toRemove->pair_.first_ != key))
  251. return false;
  252. // Fix the previous link. However, do not set the head node as a previous link
  253. Node* prev = toRemove->GetPrev();
  254. Node* next = toRemove->GetNext(0);
  255. if (next)
  256. next->SetPrev(prev != head_ ? prev : 0);
  257. // Fix the next links
  258. for (unsigned j = 0; j < height_; ++j)
  259. {
  260. Node* fixNext = fix_[j]->GetNext(j);
  261. if (fixNext)
  262. fix_[j]->SetNext(j, fixNext->GetNext(j));
  263. }
  264. // Check if height should be changed
  265. while (height_ > 0)
  266. {
  267. if (head_->GetNext(height_ - 1))
  268. break;
  269. head_->SetNext(--height_, 0);
  270. }
  271. DeleteNode(toRemove);
  272. --size_;
  273. return true;
  274. }
  275. /// Erase by an iterator. Return an iterator to the next element
  276. Iterator Erase(const Iterator& it)
  277. {
  278. if (it)
  279. {
  280. Iterator current = it++;
  281. Erase(current->first_);
  282. }
  283. return it;
  284. }
  285. /// Erase by a range of iterators. Return the end iterator
  286. Iterator Erase(const Iterator& start, const Iterator& end)
  287. {
  288. Iterator it = start;
  289. while (it != end)
  290. {
  291. Iterator current = it++;
  292. // Break if the iterator got stuck
  293. if (it == current)
  294. break;
  295. Erase(current->first_);
  296. }
  297. return it;
  298. }
  299. /// Clear the map
  300. void Clear()
  301. {
  302. // Let the head and tails node remain, but reset the next pointers
  303. Node* node = head_->GetNext(0);
  304. for (unsigned i = 0; i < maxHeight_; ++i)
  305. {
  306. head_->SetNext(i, tail_);
  307. tail_->SetNext(i, 0);
  308. tail_->SetPrev(0);
  309. }
  310. // Then remove all the key nodes
  311. while (node != tail_)
  312. {
  313. Node* current = node;
  314. node = node->GetNext(0);
  315. DeleteNode(current);
  316. }
  317. height_ = 0;
  318. size_ = 0;
  319. }
  320. /// Return iterator to the node with key, or null iterator if not found
  321. Iterator Find(const T& key) { return Iterator(FindNode(key)); }
  322. /// Return const iterator to the node with key, or null iterator if not found
  323. ConstIterator Find(const T& key) const { return ConstIterator(FindNode(key)); }
  324. /// Return iterator to the first actual node
  325. Iterator Begin() { return Iterator(head_->next_[0]); }
  326. /// Return iterator to the first actual node
  327. ConstIterator Begin() const { return ConstIterator(head_->next_[0]); }
  328. /// Return iterator to the end
  329. Iterator End() { return Iterator(tail_); }
  330. /// Return iterator to the end
  331. ConstIterator End() const { return ConstIterator(tail_); }
  332. /// Return whether contains a key
  333. bool Contains(const T& key) const { return FindNode(key) != 0; }
  334. /// Return number of keys
  335. unsigned Size() const { return size_; }
  336. /// Return current height
  337. unsigned Height() const { return height_; }
  338. /// Return whether map is empty
  339. bool Empty() const { return size_ == 0; }
  340. static const unsigned MAX_HEIGHT = 15;
  341. private:
  342. /// Find a key from the map. Return null if not found
  343. Node* FindNode(const T& key) const
  344. {
  345. Node* i = head_;
  346. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  347. {
  348. for (;;)
  349. {
  350. Node* next = i->GetNext(j);
  351. if ((next) && (next != tail_) && (key > next->pair_.first_))
  352. i = next;
  353. else
  354. break;
  355. }
  356. }
  357. Node* next = i->GetNext(0);
  358. if ((next) && (next != tail_) && (next->pair_.first_ == key))
  359. return next;
  360. else
  361. return 0;
  362. }
  363. /// Insert into the map with a specific height. Zero height will randomize. Return the node
  364. Node* InsertNode(const Pair<T, U>& pair, unsigned height)
  365. {
  366. Node* i = head_;
  367. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  368. {
  369. for (;;)
  370. {
  371. Node* next = i->GetNext(j);
  372. if ((next) && (next != tail_) && (pair.first_ > next->pair_.first_))
  373. i = next;
  374. else
  375. break;
  376. }
  377. fix_[j] = i;
  378. }
  379. // Check if key already exists, in that case only modify the value
  380. Node* next = i->GetNext(0);
  381. if ((next) && (next != tail_) && (next->pair_.first_ == pair.first_))
  382. {
  383. next->pair_.second_ = pair.second_;
  384. return next;
  385. }
  386. // Create new node, assign height and key
  387. if (!height)
  388. height = GetHeight();
  389. Node* newNode = AllocateNode(height, pair.first_);
  390. newNode->pair_.second_ = pair.second_;
  391. // Fix the previous link, however do not set the head node as previous
  392. if (i != head_)
  393. newNode->SetPrev(i);
  394. if (next)
  395. next->SetPrev(newNode);
  396. while (newNode->height_ > height_)
  397. fix_[height_++] = head_;
  398. for (unsigned h = 0; h < newNode->height_; ++h)
  399. {
  400. newNode->SetNext(h, fix_[h]->GetNext(h));
  401. fix_[h]->SetNext(h, newNode);
  402. }
  403. ++size_;
  404. return newNode;
  405. }
  406. /// Generate a random height for a new node
  407. unsigned GetHeight()
  408. {
  409. unsigned height = 1;
  410. while ((height < maxHeight_) && (GetBit()))
  411. ++height;
  412. return height;
  413. }
  414. /// Return a random true/false result
  415. bool GetBit()
  416. {
  417. if (!bitsLeft_)
  418. {
  419. random_ = rand();
  420. bitsLeft_ = 15;
  421. }
  422. bool ret = (random_ & 1) != 0;
  423. random_ >>= 1;
  424. --bitsLeft_;
  425. return ret;
  426. }
  427. /// Allocate a node and its next pointers
  428. Node* AllocateNode(unsigned height, const T& key)
  429. {
  430. unsigned char* block = new unsigned char[sizeof(Node) + (height - 1) * sizeof(Node*)];
  431. Node* newNode = reinterpret_cast<Node*>(block);
  432. // Construct the pair with placement new and map the next pointers' address
  433. new(&newNode->pair_) KeyValue(key);
  434. newNode->height_ = height;
  435. if (height > 1)
  436. newNode->levels_ = reinterpret_cast<SkipListNodeBase**>(block + sizeof(Node));
  437. else
  438. newNode->levels_ = 0;
  439. return newNode;
  440. }
  441. /// Delete a node
  442. void DeleteNode(Node* node)
  443. {
  444. // Destruct the pair, then delete the memory block
  445. (&node->pair_)->~KeyValue();
  446. delete[] reinterpret_cast<unsigned char*>(node);
  447. }
  448. /// Head node pointer
  449. Node* head_;
  450. /// Tail node pointer
  451. Node* tail_;
  452. /// Fixup pointers for insert & erase
  453. Node** fix_;
  454. /// Maximum height
  455. unsigned maxHeight_;
  456. /// Current height
  457. unsigned height_;
  458. /// Number of keys
  459. unsigned size_;
  460. /// Random bits
  461. unsigned short random_;
  462. /// Random bits remaining
  463. unsigned short bitsLeft_;
  464. };